CH582 有线键盘转蓝牙键盘
结合USB-HOST和蓝牙HID键盘的例程制作了一个有线键盘转蓝牙键盘的设备,代码如下:
/******************************************************************************/
/* 头文件包含 */
#include "CONFIG.h"
#include "HAL.h"
#include "hiddev.h"
#include "hidkbd.h"
/*********************************************************************
* GLOBAL TYPEDEFS
*/
__attribute__((aligned(4))) uint32_t MEM_BUF[BLE_MEMHEAP_SIZE / 4];
__attribute__((aligned(4))) uint8_t RxBuffer[MAX_PACKET_SIZE]; // IN, must even address
__attribute__((aligned(4))) uint8_t TxBuffer[MAX_PACKET_SIZE]; // OUT, must even address
extern uint8_t need_send;
#if(defined(BLE_MAC)) && (BLE_MAC == TRUE)
const uint8_t MacAddr[6] = {0x84, 0xC2, 0xE4, 0x03, 0x02, 0x02};
#endif
/*********************************************************************
* @fn Main_Circulation
*
* [url=home.php?mod=space&uid=159083]@brief[/url] 主循环
*
* [url=home.php?mod=space&uid=784970]@return[/url] none
*/
__HIGH_CODE
void Main_Circulation()
{
TMOS_SystemProcess();
}
/*********************************************************************
* @fn main
*
* @brief 主函数
*
* @return none
*/
int main(void)
{
uint8_t i, s, k, len, endp;
uint16_t loc;
#if(defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)
PWR_DCDCCfg(ENABLE);
#endif
SetSysClock(CLK_SOURCE_PLL_60MHz);
#if(defined(HAL_SLEEP)) && (HAL_SLEEP == TRUE)
GPIOA_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
GPIOB_ModeCfg(GPIO_Pin_All, GPIO_ModeIN_PU);
#endif
/* 开启电压监控 */
PowerMonitor(ENABLE, HALevel_2V1);
#ifdef DEBUG
GPIOA_SetBits(bTXD1);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
#endif
PRINT("%s\n", VER_LIB);
CH58X_BLEInit();
HAL_Init();
GAPRole_PeripheralInit();
HidDev_Init();
HidEmu_Init();
PRINT("Start @ChipID=%02X\n", R8_CHIP_ID);
pU2HOST_RX_RAM_Addr = RxBuffer;
pU2HOST_TX_RAM_Addr = TxBuffer;
USB2_HostInit();
PRINT("Wait Device In\n");
while(1)
{
Main_Circulation();
s = ERR_SUCCESS;
if(R8_USB2_INT_FG & RB_UIF_DETECT)
{ // 如果有USB主机检测中断则处理
R8_USB2_INT_FG = RB_UIF_DETECT;
s = AnalyzeRootU2Hub();
if(s == ERR_USB_CONNECT)
FoundNewU2Dev = 1;
}
if(FoundNewU2Dev || s == ERR_USB_CONNECT)
{ // 有新的USB设备插入
FoundNewU2Dev = 0;
mDelaymS(200); // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
s = InitRootU2Device(); // 初始化USB设备
if(s != ERR_SUCCESS)
{
PRINT("EnumAllRootDev err = %02X\n", (uint16_t)s);
}
}
/* 如果下端连接的是HUB,则先枚举HUB */
s = EnumAllU2HubPort(); // 枚举所有ROOT-HUB端口下外部HUB后的二级USB设备
if(s != ERR_SUCCESS)
{ // 可能是HUB断开了
PRINT("EnumAllHubPort err = %02X\n", (uint16_t)s);
}
/* 如果设备是键盘 */
loc = U2SearchTypeDevice(DEV_TYPE_KEYBOARD); // 在ROOT-HUB以及外部HUB各端口上搜索指定类型的设备所在的端口号
if(loc != 0xFFFF)
{ // 找到了,如果有两个KeyBoard如何处理?
i = (uint8_t)(loc >> 8);
len = (uint8_t)loc;
SelectU2HubPort(len); // 选择操作指定的ROOT-HUB端口,设置当前USB速度以及被操作设备的USB地址
endp = len ? DevOnU2HubPort[len - 1].GpVar[0] : ThisUsb2Dev.GpVar[0]; // 中断端点的地址,位7用于同步标志位
if(endp & USB_ENDP_ADDR_MASK)
{ // 端点有效
s = USB2HostTransact(USB_PID_IN << 4 | endp & 0x7F, endp & 0x80 ? RB_UH_R_TOG | RB_UH_T_TOG : 0, 0); // 传输事务,获取数据,NAK不重试
if(s == ERR_SUCCESS)
{
endp ^= 0x80; // 同步标志翻转
if(len)
DevOnU2HubPort[len - 1].GpVar[0] = endp; // 保存同步标志位
else
ThisUsb2Dev.GpVar[0] = endp;
len = R8_USB2_RX_LEN; // 接收到的数据长度
if(len)
{
U2SETorOFFNumLock(RxBuffer);
PRINT("keyboard data: ");
for(i = 0; i < len; i++)
{
PRINT("x%02X ", (uint16_t)(RxBuffer[i]));
}
PRINT("\n");
need_send = 1;
}
}
else if(s != (USB_PID_NAK | ERR_USB_TRANSFER))
{
PRINT("keyboard error %02x\n", (uint16_t)s); // 可能是断开了
}
}
else
{
PRINT("keyboard no interrupt endpoint\n");
}
SetUsb2Speed(1); // 默认为全速
}
}
}
/******************************** endfile @ main ******************************/
设置need_send全局变量作为标志位,对于蓝牙HID线程修改如下:
if(events & START_REPORT_EVT)
{
if (need_send) {
HidDev_Report(HID_RPT_ID_KEY_IN, HID_REPORT_TYPE_INPUT,
HID_KEYBOARD_IN_RPT_LEN, RxBuffer);
need_send = 0;
}
tmos_start_task(hidEmuTaskId, START_REPORT_EVT, 1);
return (events ^ START_REPORT_EVT);
}
将HID线程的周期改为1ms来提高蓝牙键盘的速度。
实物: