Initial public release.

This commit is contained in:
Joe Kearney 2025-02-01 19:22:12 -06:00
parent 7b169e8116
commit dac4af8d25
255 changed files with 68595 additions and 2 deletions

View file

@ -0,0 +1,505 @@
/*******************************************************************************
* 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 */