/****************************************************************************
Copyright (C) Cambridge Silicon Radio 2002
FILE
events.c - file for handling events generated by VM and HIDEngine
MODIFICATION HISTORY
*****************************************************************************/
#include <stdlib.h>
#include <debounce.h>
#include <event.h>
#include <message.h>
#include <sched.h>
#include <vm.h>
#include <ps.h>
#include <timer.h>
#include <pio.h>
#include <batt.h>
#include <hid.h>
#include "keyboard.h"
/*
Globals
*/
extern DEVICE_STATE_T dev_state;
extern Delay DiscoverableLEDFlasher(TimerHandle h);
/*
Prototypes for static functions
*/
static void handleInitCfm(const HID_INIT_CFM_T *prim);
static void handleConnectCfm(const HID_CONNECT_CFM_T *prim);
static void handleDisconnectInd(const HID_DISCONNECT_IND_T *prim);
static void handleDisconnectCfm(void);
static void handlePinRequest(void);
static void handlePowerMode(const HID_POWER_MODE_IND_T *prim);
static void handleButtonPress(void);
/*
This is called by the VM to tell us about our battery level
*/
void handleBatteryReading(uint16 millivolts)
{
/* only monitor battery if in report mode and active */
if ((dev_state.protocol == HIDPROTOCOL_REPORT) && (dev_state.power_mode==0))
{
/* send report */
sendBatteryReport(millivolts);
}
}
/*
This is called by the VM when one of the mask PIO lines changes
*/
static void applicationPioEvent(uint16 pins)
{
/* is button down? */
if(pins & CONNECT_BUTTON)
handleButtonPress();
}
/*
Define scheduler behaviour to call function above on button press.
*/
static const uint16 applicationPins = CONNECT_BUTTON;
const SchedPioEntry applicationPioEntry = { &applicationPins, applicationPioEvent };
/*
Responds to the user pressing the connect button.
We always want to get into discoverable mode and if
possible tell the current host that we no longer want
to be associated with it.
*/
static void handleButtonPress(void)
{
/* clear flag */
dev_state.button_press_pending = FALSE;
/* process button press depending on our current state */
switch (dev_state.state)
{
case unconnected:
/* unconnected so start discoverable */
connect(host_to_discover_and_connect);
break;
case connected:
/* still unable to process request */
dev_state.button_press_pending = TRUE;
/* button pressed during connect - unplug virtual cable */
disconnect(TRUE);
break;
case connecting:
/* we can't handle this now, so mark pending button press and try
to cancel connection */
dev_state.button_press_pending = TRUE;
cancelConnect();
break;
case disconnecting:
/* wait for disconnect to finish before processing */
dev_state.button_press_pending = TRUE;
break;
case discoverable:
/* cancel current discoverable mode and restart.
this allows user to extend the discoverable period. */
dev_state.button_press_pending = TRUE;
cancelConnect();
break;
case init:
/* ignore when initialising */
}
}
/*
This is called when the HIDEngine has posted us a message.
*/
DECLARE_TASK(2)
{
MessageType type;
void *data = MessageGet(2,&type);
if (data)
{
/* handle the message depending on its type */
switch(type)
{
/*
HID Engine events - defined below
*/
case HID_INIT_CFM:
handleInitCfm((HID_INIT_CFM_T*)data);
break;
case HID_CONNECT_CFM:
handleConnectCfm((HID_CONNECT_CFM_T*)data);
break;
case HID_DISCONNECT_IND:
handleDisconnectInd((HID_DISCONNECT_IND_T*)data);
break;
case HID_DISCONNECT_CFM:
handleDisconnectCfm();
break;
case HID_PIN_CODE_IND:
handlePinRequest();
break;
case HID_POWER_MODE_IND:
handlePowerMode((HID_POWER_MODE_IND_T*)data);
break;
/*
Protocol events - see protocol.c
*/
case HID_CONTROL_IND:
handleControl((HID_CONTROL_IND_T*)data);
break;
case HID_SET_PROTOCOL_IND:
handleSetProtocol((HID_SET_PROTOCOL_IND_T*)data);
break;
case HID_GET_PROTOCOL_IND:
handleGetProtocol((HID_GET_PROTOCOL_IND_T*)data);
break;
case HID_SET_IDLE_IND:
handleSetIdle((HID_SET_IDLE_IND_T*)data);
break;
case HID_GET_IDLE_IND:
handleGetIdle((HID_GET_IDLE_IND_T*)data);
break;
case HID_GET_REPORT_IND:
handleGetReport((HID_GET_REPORT_IND_T*)data);
break;
case HID_SET_REPORT_IND:
handleSetReport((HID_SET_REPORT_IND_T*)data);
break;
default:
}
/* free the message */
MessageDestroy(data);
}
}
/*
The HIDEngine has responded to our initialisation request.
*/
static void handleInitCfm(const HID_INIT_CFM_T *prim)
{
if (prim->result == RES_SUCCESS)
{
/* we are now unconnected */
dev_state.state = unconnected;
/* if we have a virtual cable, we will try and reconnect now */
if (dev_state.virtual_cable)
{
/* attempt to reconnect */
connect(reconnect_to_host);
}
else
{
/* power on with no virtual cable - allow ourselves to be discovered */
connect(host_to_discover_and_connect);
}
}
}
/*
A response to our CONNECT_REQ has been generated.
*/
static void handleConnectCfm(const HID_CONNECT_CFM_T *prim)
{
/* stop the discoverable flasher */
TimerCancelCallback(DiscoverableLEDFlasher);
/* are we connected? */
if (prim->result == RES_SUCCESS)
{
uint8 leds = 0;
/* if this first connection after discovery we have new virtual cable */
if (dev_state.state == discoverable)
{
/* store virtual cable info */
dev_state.host_addr = prim->host_addr;
(void)PsStore(0,&dev_state.host_addr,sizeof(BD_ADDR_T));
dev_state.virtual_cable = TRUE;
/* turn our LEDs off. this is only done on first connection
as we must preserve the LED state across connections. */
dev_state.led_state = 0;
}
/* set LEDs to last known state */
if (dev_state.led_state & 1) leds |= NUM_LOCK;
if (dev_state.led_state & 2) leds |= CAPS_LOCK;
if (dev_state.led_state & 4) leds |= SCROLL_LOCK;
PioSet(NUM_LOCK | CAPS_LOCK | SCROLL_LOCK, leds);
/* now connected */
dev_state.state = connected;
/*
start the battery monitor
(batt lib takes four samples before return value, so pass 1/4 time)
*/
BattInit(VM_ADC_TEST_A, D_SEC((BATTERY_SAMPLE_RATE+3)/4));
/* if the connect button was pressed during a connect scenario, handle it now */
if (dev_state.button_press_pending)
{
handleButtonPress();
}
}
else
{
/* turn off LEDs used to indicate our connection scenario */
PioSet(NUM_LOCK | CAPS_LOCK | SCROLL_LOCK, 0);
/* failed - still unconnected */
dev_state.state = unconnected;
/* if the connect button was pressed during a connect scenario, handle it now */
if (dev_state.button_press_pending)
{
handleButtonPress();
}
else if (dev_state.virtual_cable)
/* if we have a virtual cabled host then attempt to reconnect
when a key is pressed */
{
connect(reconnect_to_host_on_data);
}
}
}
/*
The HID connection has be terminated
*/
static void handleDisconnectInd(const HID_DISCONNECT_IND_T *prim)
{
prim = prim;
/* turn off LEDs to save power */
PioSet(NUM_LOCK | CAPS_LOCK | SCROLL_LOCK, 0);
/* we are now unconnected - reset state */
dev_state.state = unconnected;
dev_state.protocol = HIDPROTOCOL_REPORT;
dev_state.idle = 0;
/* disable IDLE signal to micro */
PioSet(IDLE_MODE,0);
/* stop the battery monitor */
BattInit(VM_ADC_TEST_A, D_NEVER);
/* look at the reason for the connection being lost and
respond accordingly */
switch (prim->reason)
{
/*
LinkLoss:
Assume that this will only occur when we are out
of range or the Host has unexpectly reset.
We will try to reconnect immediately to regain
the
蓝牙键盘源代码
4星 · 超过85%的资源 需积分: 44 55 浏览量
2018-01-25
11:32:13
上传
评论 2
收藏 12KB RAR 举报
a651912528
- 粉丝: 0
- 资源: 1
最新资源
- 细胞的奇迹:吃出来的免疫力(美亚畅销书!作者的TED演讲播放量超300万次!《谷物大脑》作者、《三联生活周刊》推荐!吃下对的食物,改善你的... (Z-Library).azw3
- 智能手机产品拆解,使用mindmaster打开
- 11111111111111
- 统信系统ARM64依赖openssl-1.0.2版本的libssl.so.10和libcrypto.so.10文件
- 奥比中光python sdk
- 冯超楠17.py
- OCR识别-基于视觉注意力机制Attention实现的OCR识别算法-附项目源码-优质项目实战.zip
- Java 使用蒙特卡洛方法估算PI的近似值(源代码)
- main.cpp
- 电子木鱼小程序源码电子木鱼小程序源码
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈