505 lines
22 KiB
C
505 lines
22 KiB
C
/*******************************************************************************
|
|
* File Name: host_main.c
|
|
*
|
|
* Version: 1.0
|
|
*
|
|
* Description:
|
|
* BLE HID keyboard example project that supports both input and output reports
|
|
* in boot and protocol mode. The example also demonstrates handling suspend
|
|
* event from the central device and enters low power mode when suspended.
|
|
*
|
|
* References:
|
|
* BLUETOOTH SPECIFICATION Version 5.0
|
|
* HID Usage Tables spec ver 1.12
|
|
*
|
|
* Hardware Dependency:
|
|
* CY8CKIT-062 PSoC6 BLE Pioneer Kit
|
|
*
|
|
******************************************************************************
|
|
* Copyright (2019), Cypress Semiconductor Corporation.
|
|
******************************************************************************
|
|
* This software is owned by Cypress Semiconductor Corporation (Cypress) and is
|
|
* protected by and subject to worldwide patent protection (United States and
|
|
* foreign), United States copyright laws and international treaty provisions.
|
|
* Cypress hereby grants to licensee a personal, non-exclusive, non-transferable
|
|
* license to copy, use, modify, create derivative works of, and compile the
|
|
* Cypress Source Code and derivative works for the sole purpose of creating
|
|
* custom software in support of licensee product to be used only in conjunction
|
|
* with a Cypress integrated circuit as specified in the applicable agreement.
|
|
* Any reproduction, modification, translation, compilation, or representation of
|
|
* this software except as specified above is prohibited without the express
|
|
* written permission of Cypress.
|
|
*
|
|
* Disclaimer: CYPRESS MAKES NO WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, WITH
|
|
* REGARD TO THIS MATERIAL, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
* Cypress reserves the right to make changes without further notice to the
|
|
* materials described herein. Cypress does not assume any liability arising out
|
|
* of the application or use of any product or circuit described herein. Cypress
|
|
* does not authorize its products for use as critical components in life-support
|
|
* systems where a malfunction or failure may reasonably be expected to result in
|
|
* significant injury to the user. The inclusion of Cypress' product in a life-
|
|
* support systems application implies that the manufacturer assumes all risk of
|
|
* such use and in doing so indemnifies Cypress against all charges. Use may be
|
|
* limited by and subject to the applicable Cypress software license agreement.
|
|
*****************************************************************************/
|
|
|
|
#include "dfu/cy_dfu.h"
|
|
#include "common.h"
|
|
#include "user_interface.h"
|
|
#include "ias.h"
|
|
#include "scps.h"
|
|
|
|
/* Global Variables */
|
|
cy_stc_ble_conn_handle_t appConnHandle;
|
|
|
|
static volatile uint32_t mainTimer = 1u;
|
|
static cy_stc_ble_timer_info_t timerParam = { .timeout = ADV_TIMER_TIMEOUT };
|
|
|
|
/* Private Function Prototypes */
|
|
static void LowPowerImplementation(void);
|
|
|
|
|
|
/*******************************************************************************
|
|
* Function Name: AppCallBack()
|
|
********************************************************************************
|
|
*
|
|
* Summary:
|
|
* This is an event callback function to receive events from the BLE Component.
|
|
*
|
|
* event - the event code
|
|
* *eventParam - the event parameters
|
|
*
|
|
*******************************************************************************/
|
|
void AppCallBack(uint32_t event, void* eventParam)
|
|
{
|
|
cy_en_ble_api_result_t apiResult;
|
|
uint8_t i;
|
|
|
|
static cy_stc_ble_gap_sec_key_info_t keyInfo =
|
|
{
|
|
.localKeysFlag = CY_BLE_GAP_SMP_INIT_ENC_KEY_DIST |
|
|
CY_BLE_GAP_SMP_INIT_IRK_KEY_DIST |
|
|
CY_BLE_GAP_SMP_INIT_CSRK_KEY_DIST,
|
|
.exchangeKeysFlag = CY_BLE_GAP_SMP_INIT_ENC_KEY_DIST |
|
|
CY_BLE_GAP_SMP_INIT_IRK_KEY_DIST |
|
|
CY_BLE_GAP_SMP_INIT_CSRK_KEY_DIST |
|
|
CY_BLE_GAP_SMP_RESP_ENC_KEY_DIST |
|
|
CY_BLE_GAP_SMP_RESP_IRK_KEY_DIST |
|
|
CY_BLE_GAP_SMP_RESP_CSRK_KEY_DIST,
|
|
};
|
|
|
|
switch (event)
|
|
{
|
|
/**********************************************************
|
|
* General Events
|
|
***********************************************************/
|
|
case CY_BLE_EVT_STACK_ON: /* This event is received when the component is Started */
|
|
DBG_PRINTF("CY_BLE_EVT_STACK_ON, StartAdvertisement \r\n");
|
|
|
|
/* Enter into discoverable mode so that remote can find it. */
|
|
apiResult = Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_FAST, CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX);
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
DBG_PRINTF("Cy_BLE_GAPP_StartAdvertisement API Error: 0x%x \r\n", apiResult);
|
|
}
|
|
|
|
/* Generates the security keys */
|
|
apiResult = Cy_BLE_GAP_GenerateKeys(&keyInfo);
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
DBG_PRINTF("Cy_BLE_GAP_GenerateKeys API Error: 0x%x \r\n", apiResult);
|
|
}
|
|
|
|
/* Display Bond list */
|
|
App_DisplayBondList();
|
|
break;
|
|
|
|
case CY_BLE_EVT_TIMEOUT:
|
|
if((((cy_stc_ble_timeout_param_t *)eventParam)->reasonCode == CY_BLE_GENERIC_APP_TO) &&
|
|
(((cy_stc_ble_timeout_param_t *)eventParam)->timerHandle == timerParam.timerHandle))
|
|
{
|
|
/* Update LED State */
|
|
UpdateLedState();
|
|
|
|
/* Indicate that timer is raised to the main loop */
|
|
mainTimer++;
|
|
|
|
/* Press and hold the mechanical button (SW2) during 4 seconds to clear the bond list. */
|
|
App_RemoveDevicesFromBondListBySW2Press(SW2_PRESS_TIME_DEL_BOND_LIST);
|
|
}
|
|
break;
|
|
|
|
case CY_BLE_EVT_HARDWARE_ERROR: /* This event indicates that some internal HW error has occurred. */
|
|
DBG_PRINTF("CY_BLE_EVT_HARDWARE_ERROR \r\n");
|
|
ShowError();
|
|
break;
|
|
|
|
/* This event will be triggered by host stack if BLE stack is busy or not busy.
|
|
* Parameter corresponding to this event will be the state of BLE stack.
|
|
* BLE stack busy = CY_BLE_STACK_STATE_BUSY,
|
|
* BLE stack not busy = CY_BLE_STACK_STATE_FREE
|
|
*/
|
|
case CY_BLE_EVT_STACK_BUSY_STATUS:
|
|
DBG_PRINTF("CY_BLE_EVT_STACK_BUSY_STATUS: %x\r\n", *(uint8_t *)eventParam);
|
|
break;
|
|
|
|
case CY_BLE_EVT_SET_TX_PWR_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_SET_TX_PWR_COMPLETE \r\n");
|
|
break;
|
|
|
|
case CY_BLE_EVT_LE_SET_EVENT_MASK_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_LE_SET_EVENT_MASK_COMPLETE \r\n");
|
|
break;
|
|
|
|
case CY_BLE_EVT_SET_DEVICE_ADDR_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_SET_DEVICE_ADDR_COMPLETE \r\n");
|
|
|
|
/* Reads the BD device address from BLE Controller's memory */
|
|
apiResult = Cy_BLE_GAP_GetBdAddress();
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
DBG_PRINTF("Cy_BLE_GAP_GetBdAddress API Error: 0x%x \r\n", apiResult);
|
|
}
|
|
break;
|
|
|
|
case CY_BLE_EVT_GET_DEVICE_ADDR_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_GET_DEVICE_ADDR_COMPLETE: ");
|
|
for(i = CY_BLE_GAP_BD_ADDR_SIZE; i > 0u; i--)
|
|
{
|
|
DBG_PRINTF("%2.2x", ((cy_stc_ble_bd_addrs_t *)
|
|
((cy_stc_ble_events_param_generic_t *)eventParam)->eventParams)->publicBdAddr[i-1]);
|
|
}
|
|
DBG_PRINTF("\r\n");
|
|
break;
|
|
|
|
case CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE \r\n");
|
|
DBG_PRINTF("Hibernate \r\n");
|
|
UART_DEB_WAIT_TX_COMPLETE();
|
|
/* Hibernate */
|
|
Cy_SysPm_Hibernate();
|
|
break;
|
|
|
|
/**********************************************************
|
|
* GAP Events
|
|
***********************************************************/
|
|
case CY_BLE_EVT_GAP_AUTH_REQ:
|
|
/* This event is received by Peripheral and Central devices. When it is received by a peripheral,
|
|
* that peripheral must Call Cy_BLE_GAPP_AuthReqReply() to reply to the authentication request
|
|
* from Central. */
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_AUTH_REQ: bdHandle=%x, security=%x, bonding=%x, ekeySize=%x, err=%x \r\n",
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).bdHandle, (*(cy_stc_ble_gap_auth_info_t *)eventParam).security,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).bonding, (*(cy_stc_ble_gap_auth_info_t *)eventParam).ekeySize,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).authErr);
|
|
|
|
if(cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX].security ==
|
|
(CY_BLE_GAP_SEC_MODE_1 | CY_BLE_GAP_SEC_LEVEL_1))
|
|
{
|
|
cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX].authErr =
|
|
CY_BLE_GAP_AUTH_ERROR_PAIRING_NOT_SUPPORTED;
|
|
}
|
|
|
|
cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX].bdHandle =
|
|
((cy_stc_ble_gap_auth_info_t *)eventParam)->bdHandle;
|
|
|
|
/* Pass security information for authentication in reply to an authentication request
|
|
* from the master device */
|
|
apiResult = Cy_BLE_GAPP_AuthReqReply(&cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX]);
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
Cy_BLE_GAP_RemoveOldestDeviceFromBondedList();
|
|
apiResult = Cy_BLE_GAPP_AuthReqReply(&cy_ble_configPtr->authInfo[CY_BLE_SECURITY_CONFIGURATION_0_INDEX]);
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
DBG_PRINTF("Cy_BLE_GAPP_AuthReqReply API Error: 0x%x \r\n", apiResult);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_PASSKEY_ENTRY_REQUEST:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_PASSKEY_ENTRY_REQUEST\r\n");
|
|
DBG_PRINTF("Please enter the passkey displayed on the peer device:\r\n");
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST: %6.6ld\r\n", *(uint32_t *)eventParam);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_NUMERIC_COMPARISON_REQUEST:
|
|
DBG_PRINTF("Compare this passkey with the one displayed in your peer device and press 'y' or 'n':"
|
|
" %6.6lu \r\n", *(uint32_t *)eventParam);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT \r\n");
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_SMP_NEGOTIATED_AUTH_INFO:"
|
|
" bdHandle=%x, security=%x, bonding=%x, ekeySize=%x, err=%x \r\n",
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).bdHandle,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).security,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).bonding,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).ekeySize,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).authErr);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_AUTH_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_AUTH_COMPLETE: bdHandle=%x, security=%x, bonding=%x, ekeySize=%x, err=%x \r\n",
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).bdHandle,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).security,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).bonding,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).ekeySize,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).authErr);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_AUTH_FAILED:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_AUTH_FAILED: bdHandle=%x, authErr=%x\r\n",
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).bdHandle,
|
|
(*(cy_stc_ble_gap_auth_info_t *)eventParam).authErr);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
|
|
DBG_PRINTF("CY_BLE_EVT_GAPP_ADVERTISEMENT_START_STOP, state: %d \r\n", Cy_BLE_GetAdvertisementState());
|
|
if((Cy_BLE_GetAdvertisementState() == CY_BLE_ADV_STATE_STOPPED) && (Cy_BLE_GetNumOfActiveConn() == 0u))
|
|
{
|
|
/* Fast and slow advertising period complete, go to low power
|
|
* mode (Hibernate) and wait for an external
|
|
* user event to wake up the device again */
|
|
UpdateLedState();
|
|
Cy_BLE_Stop();
|
|
}
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_DEVICE_CONNECTED:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_DEVICE_CONNECTED: connIntv = %d ms \r\n",
|
|
((cy_stc_ble_gap_connected_param_t *)eventParam)->connIntv * 5u /4u); /* in milliseconds / 1.25ms */
|
|
|
|
|
|
|
|
/* Set security keys for new device which is not already bonded */
|
|
if(App_IsDeviceInBondList((*(cy_stc_ble_gap_connected_param_t *)eventParam).bdHandle) == 0u)
|
|
{
|
|
keyInfo.SecKeyParam.bdHandle = (*(cy_stc_ble_gap_connected_param_t *)eventParam).bdHandle;
|
|
apiResult = Cy_BLE_GAP_SetSecurityKeys(&keyInfo);
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
DBG_PRINTF("Cy_BLE_GAP_SetSecurityKeys API Error: 0x%x \r\n", apiResult);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CY_BLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP:
|
|
DBG_PRINTF("CY_BLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP, result = %d\r\n",
|
|
(*(cy_stc_ble_l2cap_conn_update_rsp_param_t *)eventParam).result);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_KEYS_GEN_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_KEYS_GEN_COMPLETE \r\n");
|
|
keyInfo.SecKeyParam = (*(cy_stc_ble_gap_sec_key_param_t *)eventParam);
|
|
Cy_BLE_GAP_SetIdAddress(&cy_ble_deviceAddress);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_CONNECTION_UPDATE_COMPLETE:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_CONNECTION_UPDATE_COMPLETE: connIntv = %d ms \r\n", /* in milliseconds / 1.25ms */
|
|
((cy_stc_ble_gap_conn_param_updated_in_controller_t *)eventParam)->connIntv * 5u /4u);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_DEVICE_DISCONNECTED:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_DEVICE_DISCONNECTED: bdHandle=%x, reason=%x, status=%x\r\n",
|
|
(*(cy_stc_ble_gap_disconnect_param_t *)eventParam).bdHandle,
|
|
(*(cy_stc_ble_gap_disconnect_param_t *)eventParam).reason,
|
|
(*(cy_stc_ble_gap_disconnect_param_t *)eventParam).status);
|
|
|
|
/* Put the device into discoverable mode so that a remote can search it. */
|
|
apiResult = Cy_BLE_GAPP_StartAdvertisement(CY_BLE_ADVERTISING_FAST, CY_BLE_PERIPHERAL_CONFIGURATION_0_INDEX);
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
DBG_PRINTF("StartAdvertisement API Error: 0x%x \r\n", apiResult);
|
|
}
|
|
break;
|
|
|
|
case CY_BLE_EVT_GAP_ENCRYPT_CHANGE:
|
|
DBG_PRINTF("CY_BLE_EVT_GAP_ENCRYPT_CHANGE: %x \r\n", *(uint8_t *)eventParam);
|
|
break;
|
|
|
|
/**********************************************************
|
|
* GATT Events
|
|
***********************************************************/
|
|
case CY_BLE_EVT_GATT_CONNECT_IND:
|
|
appConnHandle = *(cy_stc_ble_conn_handle_t *)eventParam;
|
|
DBG_PRINTF("CY_BLE_EVT_GATT_CONNECT_IND: %x, %x \r\n",
|
|
(*(cy_stc_ble_conn_handle_t *)eventParam).attId, (*(cy_stc_ble_conn_handle_t *)eventParam).bdHandle);
|
|
|
|
break;
|
|
|
|
case CY_BLE_EVT_GATT_DISCONNECT_IND:
|
|
DBG_PRINTF("CY_BLE_EVT_GATT_DISCONNECT_IND: %x, %x \r\n",
|
|
(*(cy_stc_ble_conn_handle_t *)eventParam).attId, (*(cy_stc_ble_conn_handle_t *)eventParam).bdHandle);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GATTS_XCNHG_MTU_REQ:
|
|
{
|
|
cy_stc_ble_gatt_xchg_mtu_param_t mtu =
|
|
{
|
|
.connHandle = ((cy_stc_ble_gatt_xchg_mtu_param_t *)eventParam)->connHandle
|
|
};
|
|
Cy_BLE_GATT_GetMtuSize(&mtu);
|
|
DBG_PRINTF("CY_BLE_EVT_GATTS_XCNHG_MTU_REQ %x, %x, final mtu= %d \r\n",
|
|
mtu.connHandle.attId, mtu.connHandle.bdHandle, mtu.mtu);
|
|
}
|
|
break;
|
|
|
|
case CY_BLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ:
|
|
DBG_PRINTF("CY_BLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ %x %x: handle: %x \r\n",
|
|
((cy_stc_ble_gatts_char_val_read_req_t *)eventParam)->connHandle.attId,
|
|
((cy_stc_ble_gatts_char_val_read_req_t *)eventParam)->connHandle.bdHandle,
|
|
((cy_stc_ble_gatts_char_val_read_req_t *)eventParam)->attrHandle);
|
|
break;
|
|
|
|
case CY_BLE_EVT_GATTS_WRITE_REQ:
|
|
DBG_PRINTF("CY_BLE_EVT_GATTS_WRITE_REQ attr handle: %4.4x , value: ",
|
|
((cy_stc_ble_gatts_write_cmd_req_param_t *)eventParam)->handleValPair.attrHandle);
|
|
for(i = 0; i < ((cy_stc_ble_gatts_write_cmd_req_param_t *)eventParam)->handleValPair.value.len; i++)
|
|
{
|
|
DBG_PRINTF("%2.2x ", ((cy_stc_ble_gatts_write_cmd_req_param_t *)eventParam)->handleValPair.value.val[i]);
|
|
}
|
|
DBG_PRINTF("\r\n");
|
|
break;
|
|
|
|
case CY_BLE_EVT_GATTS_INDICATION_DISABLED:
|
|
DBG_PRINTF("CY_BLE_EVT_GATTS_INDICATION_DISABLED \r\n");
|
|
break;
|
|
|
|
case CY_BLE_EVT_GATTS_INDICATION_ENABLED:
|
|
DBG_PRINTF("CY_BLE_EVT_GATTS_INDICATION_ENABLED \r\n");
|
|
break;
|
|
|
|
/**********************************************************
|
|
* Other Events
|
|
***********************************************************/
|
|
case CY_BLE_EVT_PENDING_FLASH_WRITE:
|
|
/* Inform application that flash write is pending. Stack internal data
|
|
* structures are modified and require to be stored in Flash using
|
|
* Cy_BLE_StoreBondingData() */
|
|
DBG_PRINTF("CY_BLE_EVT_PENDING_FLASH_WRITE\r\n");
|
|
break;
|
|
|
|
default:
|
|
DBG_PRINTF("Other event: 0x%lx \r\n", event);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* Function Name: LowPowerImplementation()
|
|
********************************************************************************
|
|
* Summary:
|
|
* Implements low power in the project.
|
|
*
|
|
* Theory:
|
|
* The function tries to enter deep sleep as much as possible - whenever the
|
|
* BLE is idle and the UART transmission/reception is not happening.
|
|
*
|
|
*******************************************************************************/
|
|
static void LowPowerImplementation(void)
|
|
{
|
|
if(UART_DEB_IS_TX_COMPLETE() != 0u)
|
|
{
|
|
/* Entering into the Deep Sleep */
|
|
Cy_SysPm_DeepSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
* Function Name: HostMain()
|
|
********************************************************************************
|
|
* Summary:
|
|
* Main function for the project.
|
|
*
|
|
*******************************************************************************/
|
|
int HostMain(void)
|
|
{
|
|
cy_en_ble_api_result_t apiResult;
|
|
|
|
/* Initialization the user interface: LEDs, SW2, ect. */
|
|
InitUserInterface();
|
|
|
|
/* Initialize Debug UART */
|
|
UART_START();
|
|
DBG_PRINTF("BLE HID Keyboard Example\r\n");
|
|
|
|
/* Start BLE component and register generic event handler */
|
|
apiResult = Cy_BLE_Start(AppCallBack);
|
|
if(apiResult != CY_BLE_SUCCESS)
|
|
{
|
|
DBG_PRINTF("Cy_BLE_Start API Error: 0x%x \r\n", apiResult);
|
|
}
|
|
|
|
/* Initialize BLE Services */
|
|
ScpsInit();
|
|
IasInit();
|
|
|
|
|
|
/***************************************************************************
|
|
* Main polling loop
|
|
***************************************************************************/
|
|
while(1)
|
|
{
|
|
/* Cy_BLE_ProcessEvents() allows BLE stack to process pending events */
|
|
Cy_BLE_ProcessEvents();
|
|
|
|
/* To achieve low power in the device */
|
|
LowPowerImplementation();
|
|
|
|
/* Restart 1s timer */
|
|
if(mainTimer != 0u)
|
|
{
|
|
mainTimer = 0u;
|
|
Cy_BLE_StartTimer(&timerParam);
|
|
}
|
|
|
|
/* Remove devices from the bond list. Should be done when no active connections */
|
|
if((Cy_BLE_GetNumOfActiveConn() == 0u) && (App_IsRemoveBondListFlag() == true))
|
|
{
|
|
App_RemoveDevicesFromBondList();
|
|
}
|
|
|
|
#if(CY_BLE_BONDING_REQUIREMENT == CY_BLE_BONDING_YES)
|
|
/* Store bonding data to flash only when all debug information has been sent */
|
|
if(cy_ble_pendingFlashWrite != 0u)
|
|
{
|
|
apiResult = Cy_BLE_StoreBondingData();
|
|
DBG_PRINTF("Store bonding data, status: %x, pending: %x \r\n", apiResult, cy_ble_pendingFlashWrite);
|
|
}
|
|
#endif /* CY_BLE_BONDING_REQUIREMENT == CY_BLE_BONDING_YES */
|
|
|
|
if (alertLevel != 0u)
|
|
{
|
|
cy_stc_ble_gap_disconnect_info_t disconnectInfoParam =
|
|
{
|
|
.bdHandle = appConnHandle.bdHandle,
|
|
.reason = CY_BLE_HCI_ERROR_OTHER_END_TERMINATED_USER
|
|
};
|
|
|
|
/* Initiate disconnection from the peer device*/
|
|
if(Cy_BLE_GAP_Disconnect(&disconnectInfoParam) == CY_BLE_SUCCESS)
|
|
{
|
|
/* Wait for disconnection event */
|
|
while(Cy_BLE_GetConnectionState(appConnHandle) == CY_BLE_CONN_STATE_CONNECTED)
|
|
{
|
|
/* Process BLE events */
|
|
Cy_BLE_ProcessEvents();
|
|
}
|
|
}
|
|
/* Stop BLE component. */
|
|
Cy_BLE_Disable();
|
|
Cy_DFU_ExecuteApp(0u);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* [] END OF FILE */
|