diff --git a/.gitignore b/.gitignore index 76f4628..4bb839f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build output +.vscode diff --git a/examples/apps/CMakeLists.txt b/examples/apps/CMakeLists.txt index 03da6f0..c2fc23e 100644 --- a/examples/apps/CMakeLists.txt +++ b/examples/apps/CMakeLists.txt @@ -30,4 +30,4 @@ if(OT_APP_CLI) add_subdirectory(cli) endif() -add_subdirectory(ncp) +#add_subdirectory(ncp) diff --git a/examples/apps/cli/CMakeLists.txt b/examples/apps/cli/CMakeLists.txt index 32f71e5..6a80faf 100644 --- a/examples/apps/cli/CMakeLists.txt +++ b/examples/apps/cli/CMakeLists.txt @@ -29,13 +29,112 @@ set(COMMON_INCLUDES ${OT_PUBLIC_INCLUDES} ${TI_PUBLIC_INCLUDES} + ${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/openthread/examples/platforms ${PROJECT_SOURCE_DIR}/openthread/src/core + + # JJM include paths for ICall module + ${TI_SIMPLELINK_SDK_DIR}/source/ti/drivers/dpl + ${TI_SIMPLELINK_SDK_DIR}/source + ${TI_SIMPLELINK_SDK_DIR}/source/ti + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/controller/cc26xx/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/rom + ${TI_SIMPLELINK_SDK_DIR}/source/ti/common/cc26xx + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/hal/src/target/_common + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx/npi/stack/ + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/hal/src/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/heapmgr + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/profiles/dev_info + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/profiles/simple_profile + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/src/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/npi/src/ + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/osal/src/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/services/src/saddr + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/services/src/sdata + ${TI_SIMPLELINK_SDK_DIR}/source/ti/common/nv + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/src + ${TI_SIMPLELINK_SDK_DIR}/kernel/tirtos7/packages + ${TI_SIMPLELINK_SDK_DIR}/source/ti/devices/cc13x4_cc26x4 + ${TI_SIMPLELINK_SDK_DIR}/source/ti/posix/gcc + + ${TI_SIMPLELINK_SDK_DIR}/kernel/freertos + ${TI_SIMPLELINK_SDK_DIR}/kernel + + # Needed for bget.h + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack/common/cc26xx/freertos ) set(COMMON_SOURCES cli_uart.cpp main.c + #bleAppTask.c + #bleStackMenu.c + app_main.c + app_data.c + app_pairing.c + app_peripheral.c + app_dev_info.c + app_simple_gatt.c + osal_icall_ble.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack/common/cc26xx/freertos/bget.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack/common/cc26xx/freertos/TI_heap_wrapper.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm/apps/common/ble_remote_display/stack/osal_icall_ble.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/rom/agama_r1/rom_init.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx/util.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx/menu/two_btn_menu.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/display/Display.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx/board_key.c + ${TI_SIMPLELINK_SDK_DIR}/kernel/nortos/dpl/SystemP_nortos.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack/common/cc26xx/freertos/bget.c +) + +set(USR_COMPILE_DEFINITIONS + "USE_DMM" + "SYSCFG" + "CC13X4" + "CC13XX" + "POWER_SAVING" + "TBM_ACTIVE_ITEMS_ONLY" + "STACK_LIBRARY" + "EXTENDED_STACK_SETTINGS=EXTENDED_STACK_SETTINGS_DEFAULT" + "NPI_USE_UART" + "ICALL_EVENTS" + "ICALL_JT" + "ICALL_LITE" + "ICALL_STACK0_ADDR" + "USE_ICALL" + "ICALL_MAX_NUM_ENTITIES=6" + "ICALL_MAX_NUM_TASKS=3" + "OSAL_CBTIMER_NUM_TASKS=1" + "ONE_BLE_LIB_SIZE_OPTIMIZATION" + + # the following are from ti_build_config.opt + "HOST_CONFIG=PERIPHERAL_CFG" + "USE_AE" + "GAP_BOND_MGR" + "HCI_TL_NONE" + "FREERTOS" + + # from basic_ble_LP_EM_CC1354P10_1_freertos_ticlang + "ICALL_NO_APP_EVENTS" + "UARTLOG_ENABLE" + "uartlog_FILE=0" + "DeviceFamily_CC13X4" + "FLASH_ONLY_BUILD" + "NVOCMP_NWSAMEITEM=1" + "EM_CC1354P10_1_LP" + "NVOCMP_POSIX_MUTEX" +) + +set(APPEND CMAKE_C_FLAGS -std=c99) + +target_compile_options(openthread-cc13xx_cc26xx + PUBLIC + -O0 ) if(TI_SIMPLELINK_KERNEL STREQUAL "freertos") @@ -48,14 +147,14 @@ else() message(FATAL_ERROR "Unsuported TI_SIMPLELINK_KERNEL: ${TI_SIMPLELINK_KERNEL}") endif() -if(OT_FTD) - include(ftd.cmake) -endif() +#if(OT_FTD) +# include(ftd.cmake) +#endif() if(OT_MTD) include(mtd.cmake) endif() -if(OT_RCP) - include(radio.cmake) -endif() +#if(OT_RCP) +# include(radio.cmake) +#endif() diff --git a/examples/apps/cli/Logger.h b/examples/apps/cli/Logger.h new file mode 100644 index 0000000..607f51a --- /dev/null +++ b/examples/apps/cli/Logger.h @@ -0,0 +1,6 @@ +#pragma once +#include + +#if OPENTHREAD_CONFIG_LOG_OUTPUT == OPENTHREAD_CONFIG_LOG_OUTPUT_APP +void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat, ...); +#endif \ No newline at end of file diff --git a/examples/apps/cli/app_data.c b/examples/apps/cli/app_data.c new file mode 100755 index 0000000..ef176eb --- /dev/null +++ b/examples/apps/cli/app_data.c @@ -0,0 +1,139 @@ +/****************************************************************************** + +@file app_data.c + +@brief This file contains the application data functionality + +Group: WCS, BTS +Target Device: cc13xx_cc26xx + +****************************************************************************** + + Copyright (c) 2022-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +****************************************************************************** + + +*****************************************************************************/ + +//***************************************************************************** +//! Includes +//***************************************************************************** +#include +#include + +//***************************************************************************** +//! Defines +//***************************************************************************** + +//***************************************************************************** +//! Globals +//***************************************************************************** + +static void GATT_EventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData); + +// Events handlers struct, contains the handlers and event masks +// of the application data module +BLEAppUtil_EventHandler_t dataGATTHandler = +{ + .handlerType = BLEAPPUTIL_GATT_TYPE, + .pEventHandler = GATT_EventHandler, + .eventMask = BLEAPPUTIL_ATT_FLOW_CTRL_VIOLATED_EVENT | + BLEAPPUTIL_ATT_MTU_UPDATED_EVENT +}; + +//***************************************************************************** +//! Functions +//***************************************************************************** + +/********************************************************************* + * @fn GATT_EventHandler + * + * @brief The purpose of this function is to handle GATT events + * that rise from the GATT and were registered in + * @ref BLEAppUtil_RegisterGAPEvent + * + * @param event - message event. + * @param pMsgData - pointer to message data. + * + * @return none + */ +static void GATT_EventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData) +{ + gattMsgEvent_t *gattMsg = ( gattMsgEvent_t * )pMsgData; + switch ( gattMsg->method ) + { + case ATT_FLOW_CTRL_VIOLATED_EVENT: + { + Display_printf( dispHandle, dispIndex, 0, + "#%5d ATT_FLOW_CTRL_VIOLATED_EVENT", + dispIndex ); dispIndex++; + } + break; + + case ATT_MTU_UPDATED_EVENT: + { + Display_printf( dispHandle, dispIndex, 0, + "#%5d ATT_MTU_UPDATED_EVENT", + dispIndex ); dispIndex++; + } + break; + + + default: + break; + } +} + +/********************************************************************* + * @fn Data_start + * + * @brief This function is called after stack initialization, + * the purpose of this function is to initialize and + * register the specific events handlers of the data + * application module + * + * @return SUCCESS, errorInfo + */ +bStatus_t Data_start( void ) +{ + bStatus_t status = SUCCESS; + + Display_printf( dispHandle, dispIndex, 0, + "#%5d Data_start: Register Handlers", + dispIndex ); dispIndex++; + + // Register the handlers + status = BLEAppUtil_registerEventHandler( &dataGATTHandler ); + + // Return status value + return( status ); +} diff --git a/examples/apps/cli/app_dev_info.c b/examples/apps/cli/app_dev_info.c new file mode 100755 index 0000000..a1bea08 --- /dev/null +++ b/examples/apps/cli/app_dev_info.c @@ -0,0 +1,109 @@ +/****************************************************************************** + +@file app_dev_info.c + +@brief This file contains the device info application functionality + +Group: WCS, BTS +Target Device: cc13xx_cc26xx + +****************************************************************************** + + Copyright (c) 2022-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +****************************************************************************** + + +*****************************************************************************/ + +//***************************************************************************** +//! Includes +//***************************************************************************** +#include +#include +#include + +//***************************************************************************** +//! Defines +//***************************************************************************** + +//***************************************************************************** +//! Globals +//***************************************************************************** + +//***************************************************************************** +//! Functions +//***************************************************************************** + +/********************************************************************* + * @fn DevInfo_start + * + * @brief This function is called after stack initialization, + * the purpose of this function is to initialize and + * register the Device Info service. + * + * @return SUCCESS or stack call status + */ + +bStatus_t DevInfo_start(void) +{ + bStatus_t status = SUCCESS; + uint8_t *devAddr = NULL; + uint8_t systemId[DEVINFO_SYSTEM_ID_LEN] = {0}; + + // Device Information Service + status = DevInfo_addService(); + if ( status != SUCCESS ) + { + // Return status value + return( status ); + } + + devAddr = GAP_GetDevAddress( TRUE ); + + memcpy( &systemId[0], &devAddr[0], 3 ); // use 6 bytes of device address for 8 bytes of system ID value + memset( &systemId[3], 0xFFFE, 2 ); // set middle bytes to 0xFFFE + memcpy( &systemId[5], &devAddr[3], 3 ); // shift three bytes up + + // Set Device Info Service System ID Parameter + status = DevInfo_setParameter( DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId ); + if ( status != SUCCESS ) + { + // Return status value + return ( status ); + } + + // Set Device Info Service Manufacturer Name Parameter + status = DevInfo_setParameter( DEVINFO_MANUFACTURER_NAME, DEVINFO_STR_ATTR_LEN, "Texas Instruments" ); + + // Return status value + return ( status ); +} diff --git a/examples/apps/cli/app_main.c b/examples/apps/cli/app_main.c new file mode 100755 index 0000000..aa28051 --- /dev/null +++ b/examples/apps/cli/app_main.c @@ -0,0 +1,263 @@ +/****************************************************************************** + +@file app_main.c + +@brief This file contains the application main functionality + +Group: WCS, BTS +Target Device: cc13xx_cc26xx + +****************************************************************************** + + Copyright (c) 2022-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +****************************************************************************** + + +*****************************************************************************/ + +//***************************************************************************** +//! Includes +//***************************************************************************** +#include "ti_ble_config.h" +#include + +//***************************************************************************** +//! Defines +//***************************************************************************** + +//***************************************************************************** +//! Globals +//***************************************************************************** + +// Parameters that should be given as input to the BLEAppUtil_init function +BLEAppUtil_GeneralParams_t appMainParams = +{ + .taskPriority = 1, + .taskStackSize = 1024, + .profileRole = (BLEAppUtil_Profile_Roles_e)(HOST_CONFIG), + .addressMode = DEFAULT_ADDRESS_MODE, + .deviceNameAtt = attDeviceName, +}; + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG | CENTRAL_CFG ) ) +BLEAppUtil_PeriCentParams_t appMainPeriCentParams = +{ +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG ) ) + .connParamUpdateDecision = DEFAULT_PARAM_UPDATE_REQ_DECISION, +#endif //#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG ) ) + .gapBondParams = &gapBondParams +}; +#else //observer || broadcaster +BLEAppUtil_PeriCentParams_t appMainPeriCentParams; +#endif //#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG | CENTRAL_CFG ) ) + + +// Display Interface +uint8 dispIndex = 0; +Display_Handle dispHandle = NULL; + +//***************************************************************************** +//! Functions +//***************************************************************************** +extern bStatus_t Peripheral_start(void); +extern bStatus_t Broadcaster_start(void); +extern bStatus_t Central_start(void); +extern bStatus_t Observer_start(void); +extern bStatus_t Pairing_start(void); +extern bStatus_t Data_start(void); +extern bStatus_t DevInfo_start(void); +extern bStatus_t SimpleGatt_start(void); +extern bStatus_t OAD_start(void); + +/********************************************************************* + * @fn criticalErrorHandler + * + * @brief Application task entry point + * + * @return none + */ +void criticalErrorHandler(int32 errorCode , void* pInfo) +{ +// trace(); +// +//#ifdef DEBUG_ERR_HANDLE +// +// while (1); +//#else +// SystemReset(); +//#endif + +} + +/********************************************************************* + * @fn openDisplay + * + * @brief Initializes and open the Display driver. + * + * @param dispHandle A handle for specific Display implementations + * + * @return SUCCESS, FAILURE + */ +static bStatus_t openDisplay(void) +{ + bStatus_t status = SUCCESS; + //Initializes the Display driver. + Display_init(); + + // Open Display. + dispHandle = Display_open(Display_Type_ANY, NULL); + if (dispHandle == NULL) + { + status = FAILURE; + } + + return status; +} + +/********************************************************************* + * @fn App_StackInitDone + * + * @brief This function will be called when the BLE stack init is + * done. + * It should call the applications modules start functions. + * + * @return none + */ +void App_StackInitDoneHandler(gapDeviceInitDoneEvent_t *deviceInitDoneData) +{ + bStatus_t status = SUCCESS; + uint8_t* pRpa; + + // Open Display. + status = openDisplay(); + if(status != SUCCESS) + { + // TODO: Call Error Handler + } + + // Print the device address + Display_printf(dispHandle, dispIndex, 0, + "#%5d BLE Device Address %s", + dispIndex, + BLEAppUtil_convertBdAddr2Str(deviceInitDoneData->devAddr)); dispIndex++; + + // Read the current RPA. + pRpa = GAP_GetDevAddress(FALSE); + + if ( appMainParams.addressMode > ADDRMODE_RANDOM) + { + // If the RPA has changed, update the display + Display_printf(dispHandle, dispIndex, 0, + "#%5d RP Addr: %s", + dispIndex, + BLEAppUtil_convertBdAddr2Str(pRpa)); dispIndex++; + } + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG ) ) + // Any device that accepts the establishment of a link using + // any of the connection establishment procedures referred to + // as being in the Peripheral role. + // A device operating in the Peripheral role will be in the + // Slave role in the Link Layer Connection state. + status = Peripheral_start(); + if(status != SUCCESS) + { + // TODO: Call Error Handler + } +#endif + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( BROADCASTER_CFG ) ) + // A device operating in the Broadcaster role is a device that + // sends advertising events or periodic advertising events + status = Broadcaster_start(); + if(status != SUCCESS) + { + // TODO: Call Error Handler + } +#endif + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( CENTRAL_CFG ) ) + // A device that supports the Central role initiates the establishment + // of an active physical link. A device operating in the Central role will + // be in the Master role in the Link Layer Connection state. + // A device operating in the Central role is referred to as a Central. + status = Central_start(); + if(status != SUCCESS) + { + // TODO: Call Error Handler + } +#endif + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( OBSERVER_CFG ) ) + // A device operating in the Observer role is a device that + // receives advertising events or periodic advertising events + status = Observer_start(); + if(status != SUCCESS) + { + // TODO: Call Error Handler + } +#endif + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG | CENTRAL_CFG ) ) + status = Pairing_start(); + status = Data_start(); + status = DevInfo_start(); + status = SimpleGatt_start(); + if(status != SUCCESS) + { + // TODO: Call Error Handler for each call + } +#endif + + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG | CENTRAL_CFG )) && defined(OAD_CFG) + status = OAD_start(); + if(status != SUCCESS) + { + // TODO: Call Error Handler + } +#endif +} + +/********************************************************************* + * @fn appMain + * + * @brief Application main function + * + * @return none + */ +void appMain(void) +{ + // Call the BLEAppUtil module init function + BLEAppUtil_init(&criticalErrorHandler, &App_StackInitDoneHandler, + &appMainParams, &appMainPeriCentParams); +} diff --git a/examples/apps/cli/app_pairing.c b/examples/apps/cli/app_pairing.c new file mode 100755 index 0000000..9ec9b9b --- /dev/null +++ b/examples/apps/cli/app_pairing.c @@ -0,0 +1,212 @@ +/****************************************************************************** + +@file app_pairing.c + +@brief This file contains the application pairing role functionality + +Group: WCS, BTS +Target Device: cc13xx_cc26xx + +****************************************************************************** + + Copyright (c) 2022-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +****************************************************************************** + + +*****************************************************************************/ + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG | CENTRAL_CFG ) ) + +//***************************************************************************** +//! Includes +//***************************************************************************** +#include + +//***************************************************************************** +//! Prototypes +//***************************************************************************** + +void Pairing_passcodeHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData); +void Pairing_pairStateHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData); + +//***************************************************************************** +//! Globals +//***************************************************************************** + +BLEAppUtil_EventHandler_t pairingPasscodeHandler = +{ + .handlerType = BLEAPPUTIL_PASSCODE_TYPE, + .pEventHandler = Pairing_passcodeHandler +}; + +BLEAppUtil_EventHandler_t PairingPairStateHandler = +{ + .handlerType = BLEAPPUTIL_PAIR_STATE_TYPE, + .pEventHandler = Pairing_pairStateHandler, + .eventMask = BLEAPPUTIL_PAIRING_STATE_STARTED | + BLEAPPUTIL_PAIRING_STATE_COMPLETE | + BLEAPPUTIL_PAIRING_STATE_ENCRYPTED | + BLEAPPUTIL_PAIRING_STATE_BOND_SAVED, +}; +//***************************************************************************** +//! Functions +//***************************************************************************** + +/********************************************************************* + * @fn Pairing_passcodeHandler + * + * @brief The purpose of this function is to handle passcode data + * that rise from the GAPBondMgr and were registered + * in @ref BLEAppUtil_RegisterGAPEvent + * + * @param pMsgData - pointer to message data. + * + * @return none + */ +void Pairing_passcodeHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData) +{ + BLEAppUtil_PasscodeData_t *pData = (BLEAppUtil_PasscodeData_t *)pMsgData; + + // Send passcode response + GAPBondMgr_PasscodeRsp(pData->connHandle, SUCCESS, B_APP_DEFAULT_PASSCODE); +} + +/********************************************************************* + * @fn Pairing_pairStateHandler + * + * @brief The purpose of this function is to handle pairing state + * events that rise from the GAPBondMgr and were registered + * in @ref BLEAppUtil_RegisterGAPEvent + * + * @param event - message event. + * @param pMsgData - pointer to message data. + * + * @return none + */ +void Pairing_pairStateHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData) +{ + switch(event) + { + case BLEAPPUTIL_PAIRING_STATE_STARTED: + { + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_STARTED: connectionHandle = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->connHandle); dispIndex++; + + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_STARTED: status = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->status); dispIndex++; + + break; + } + case BLEAPPUTIL_PAIRING_STATE_COMPLETE: + { + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_COMPLETE: connectionHandle = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->connHandle); dispIndex++; + + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_COMPLETE: status = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->status); dispIndex++; + break; + } + + case BLEAPPUTIL_PAIRING_STATE_ENCRYPTED: + { + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_ENCRYPTED: connectionHandle = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->connHandle); dispIndex++; + + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_ENCRYPTED: status = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->status); dispIndex++; + break; + } + + case BLEAPPUTIL_PAIRING_STATE_BOND_SAVED: + { + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_BOND_SAVED: connectionHandle = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->connHandle); dispIndex++; + + Display_printf(dispHandle, dispIndex, 0, + "#%5d PAIRING_STATE_BOND_SAVED: status = %d", + dispIndex, + ((BLEAppUtil_PairStateData_t *)pMsgData)->status); dispIndex++; + break; + } + + default: + { + break; + } + } + +} + +/********************************************************************* + * @fn Pairing_start + * + * @brief This function is called after stack initialization, + * the purpose of this function is to initialize and + * register the specific events handlers of the pairing + * application module + * + * @return SUCCESS, errorInfo + */ +bStatus_t Pairing_start() +{ + bStatus_t status; + + Display_printf(dispHandle, dispIndex, 0, + "#%5d Pairing_start: Register Handlers", + dispIndex); dispIndex++; + + // Register the handlers + status = BLEAppUtil_registerEventHandler(&pairingPasscodeHandler); + status = BLEAppUtil_registerEventHandler(&PairingPairStateHandler); + if(status != SUCCESS) + { + return(status); + } + + return SUCCESS; +} + +#endif // ( HOST_CONFIG & ( PERIPHERAL_CFG | CENTRAL_CFG ) ) diff --git a/examples/apps/cli/app_peripheral.c b/examples/apps/cli/app_peripheral.c new file mode 100755 index 0000000..f919ae3 --- /dev/null +++ b/examples/apps/cli/app_peripheral.c @@ -0,0 +1,314 @@ +/****************************************************************************** + +@file app_peripheral.c + +@brief This example file demonstrates how to activate the peripheral role with +the help of BLEAppUtil APIs. + +Two structures are used for event handling, one for connection events and one +for advertising events. +In each, eventMask is used to specify the events that will be received +and handled. +In addition, fill the BLEAppUtil_AdvInit_t structure with variables generated +by the Sysconfig. + +In the events handler functions, write what actions are done after each event. +In this example, after a connection is made, activation is performed for +re-advertising up to the maximum connections. + +In the Peripheral_start() function at the bottom of the file, registration, +initialization and activation are done using the BLEAppUtil API functions, +using the structures defined in the file. + +More details on the functions and structures can be seen next to the usage. + +Group: WCS, BTS +Target Device: cc13xx_cc26xx + +****************************************************************************** + + Copyright (c) 2022-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +****************************************************************************** + + +*****************************************************************************/ + +#if defined( HOST_CONFIG ) && ( HOST_CONFIG & ( PERIPHERAL_CFG ) ) + +//***************************************************************************** +//! Includes +//***************************************************************************** +#include "ti_ble_config.h" +#include + +//***************************************************************************** +//! Prototypes +//***************************************************************************** +void Peripheral_AdvEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData); +void Peripheral_GAPConnEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData); + +//***************************************************************************** +//! Globals +//***************************************************************************** + +BLEAppUtil_EventHandler_t peripheralConnHandler = +{ + .handlerType = BLEAPPUTIL_GAP_CONN_TYPE, + .pEventHandler = Peripheral_GAPConnEventHandler, + .eventMask = BLEAPPUTIL_LINK_ESTABLISHED_EVENT | + BLEAPPUTIL_LINK_PARAM_UPDATE_REQ_EVENT | + BLEAPPUTIL_LINK_TERMINATED_EVENT, +}; + +BLEAppUtil_EventHandler_t peripheralAdvHandler = +{ + .handlerType = BLEAPPUTIL_GAP_ADV_TYPE, + .pEventHandler = Peripheral_AdvEventHandler, + .eventMask = BLEAPPUTIL_ADV_START_AFTER_ENABLE | + BLEAPPUTIL_ADV_END_AFTER_DISABLE +}; + +//! Store handle needed for each advertise set +uint8 peripheralAdvHandle_1; + +//! Advertise param, needed for each advertise set, Generate by Sysconfig +const BLEAppUtil_AdvInit_t advSetInitParamsSet_1 = +{ + /* Advertise data and length */ + .advDataLen = sizeof(advData1), + .advData = advData1, + + /* Scan respond data and length */ + .scanRespDataLen = sizeof(scanResData1), + .scanRespData = scanResData1, + + .advParam = &advParams1 +}; + +const BLEAppUtil_AdvStart_t advSetStartParamsSet_1 = +{ + /* Use the maximum possible value. This is the spec-defined maximum for */ + /* directed advertising and infinite advertising for all other types */ + .enableOptions = GAP_ADV_ENABLE_OPTIONS_USE_MAX, + .durationOrMaxEvents = 0 +}; + +//***************************************************************************** +//! Functions +//***************************************************************************** + +/********************************************************************* + * @fn Peripheral_AdvEventHandler + * + * @brief The purpose of this function is to handle advertise events + * that rise from the GAP and were registered in + * @ref BLEAppUtil_RegisterGAPEvent + * + * @param event - message event. + * @param pMsgData - pointer to message data. + * + * @return none + */ +void Peripheral_AdvEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData) +{ + switch(event) + { + case BLEAPPUTIL_ADV_START_AFTER_ENABLE: + { + Display_printf(dispHandle, dispIndex, 0, + "#%5d ADV_START_AFTER_ENABLE: Peripheral role, advhandle: %d", + dispIndex, + ((BLEAppUtil_AdvEventData_t *)pMsgData)->pBuf->advHandle); dispIndex++; + break; + } + + case BLEAPPUTIL_ADV_END_AFTER_DISABLE: + { + Display_printf(dispHandle, dispIndex, 0, + "#%5d ADV_END_AFTER_DISABLE: Peripheral role, advhandle: %d", + dispIndex, + ((BLEAppUtil_AdvEventData_t *)pMsgData)->pBuf->advHandle); dispIndex++; + break; + } + + default: + { + break; + } + } +} + +/********************************************************************* + * @fn Peripheral_GAPConnEventHandler + * + * @brief The purpose of this function is to handle connection related + * events that rise from the GAP and were registered in + * @ref BLEAppUtil_RegisterGAPEvent + * + * @param event - message event. + * @param pMsgData - pointer to message data. + * + * @return none + */ +void Peripheral_GAPConnEventHandler(uint32 event, BLEAppUtil_msgHdr_t *pMsgData) +{ + switch(event) + { + case BLEAPPUTIL_LINK_ESTABLISHED_EVENT: + { + + if(((gapEstLinkReqEvent_t *)pMsgData)->connRole == BLEAPPUTIL_PERIPHERAL_ROLE) + { + /*! Print the peer address and connection handle number */ + Display_printf(dispHandle, dispIndex, 0, + "#%5d LINK_ESTABLISHED_EVENT: Peripheral role " + "Connected to %s, connectionHandle = %d", + dispIndex, + BLEAppUtil_convertBdAddr2Str(((gapEstLinkReqEvent_t *)pMsgData)->devAddr), + ((gapEstLinkReqEvent_t *)pMsgData)->connectionHandle); dispIndex++; + + /*! Print the number of current connections */ + Display_printf(dispHandle, dispIndex, 0, + "#%5d LINK_ESTABLISHED_EVENT: Peripheral role " + "Num Conns = %d", + dispIndex, + linkDB_NumActive()); dispIndex++; + } + /* Check if we reach the maximum allowed number of connections */ + if(linkDB_NumActive() < linkDB_NumConns()) + { + /* Start advertising since there is room for more connections */ + BLEAppUtil_advStart(peripheralAdvHandle_1, &advSetStartParamsSet_1); + } + else + { + /* Stop advertising since there is no room for more connections */ + BLEAppUtil_advStop(peripheralAdvHandle_1); + } + break; + } + + case BLEAPPUTIL_LINK_TERMINATED_EVENT: + { + + /*! Print the connHandle and termination reason */ + Display_printf(dispHandle, dispIndex, 0, + "#%5d LINK_TERMINATED_EVENT: Peripheral role, " + "connectionHandle = %d, reason = %d", + dispIndex, + ((gapTerminateLinkEvent_t *)pMsgData)->connectionHandle, + ((gapTerminateLinkEvent_t *)pMsgData)->reason); dispIndex++; + + /*! Print the number of current connections */ + Display_printf(dispHandle, dispIndex, 0, + "#%5d LINK_TERMINATED_EVENT: Peripheral role, " + "Num Conns = %d", + dispIndex, + linkDB_NumActive()); dispIndex++; + + BLEAppUtil_advStart(peripheralAdvHandle_1, &advSetStartParamsSet_1); + break; + } + case BLEAPPUTIL_LINK_PARAM_UPDATE_REQ_EVENT: + { + gapUpdateLinkParamReqEvent_t *pReq = (gapUpdateLinkParamReqEvent_t *)pMsgData; + + // Only accept connection intervals with peripheral latency of 0 + // This is just an example of how the application can send a response + if(pReq->req.connLatency == 0) + { + BLEAppUtil_paramUpdateRsp(pReq,TRUE); + } + else + { + BLEAppUtil_paramUpdateRsp(pReq,FALSE); + } + + break; + } + + default: + { + break; + } + } +} + +/********************************************************************* + * @fn Peripheral_start + * + * @brief This function is called after stack initialization, + * the purpose of this function is to initialize and + * register the specific events handlers of the peripheral + * application module + * + * @return SUCCESS, errorInfo + */ +bStatus_t Peripheral_start() +{ + bStatus_t status; + + Display_printf(dispHandle, dispIndex, 0, + "#%5d Peripheral_start: Register Handlers", + dispIndex); dispIndex++; + + status = BLEAppUtil_registerEventHandler(&peripheralConnHandler); + status = BLEAppUtil_registerEventHandler(&peripheralAdvHandler); + if(status != SUCCESS) + { + return(status); + } + + Display_printf(dispHandle, dispIndex, 0, + "#%5d Peripheral_start: Init Adv Set 1", + dispIndex); dispIndex++; + + status = BLEAppUtil_initAdvSet(&peripheralAdvHandle_1, &advSetInitParamsSet_1); + if(status != SUCCESS) + { + return(status); + } + + Display_printf(dispHandle, dispIndex, 0, + "#%5d Peripheral_start: Start Adv Set 1", + dispIndex); dispIndex++; + + status = BLEAppUtil_advStart(peripheralAdvHandle_1, &advSetStartParamsSet_1); + if(status != SUCCESS) + { + return(status); + } + + return SUCCESS; +} + +#endif // ( HOST_CONFIG & ( PERIPHERAL_CFG ) ) diff --git a/examples/apps/cli/app_simple_gatt.c b/examples/apps/cli/app_simple_gatt.c new file mode 100755 index 0000000..60c71a5 --- /dev/null +++ b/examples/apps/cli/app_simple_gatt.c @@ -0,0 +1,200 @@ +/****************************************************************************** + +@file app_simple_gatt.c + +@brief This file contains the Simple GATT application functionality + +Group: WCS, BTS +Target Device: cc13xx_cc26xx + +****************************************************************************** + + Copyright (c) 2022-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +****************************************************************************** + + +*****************************************************************************/ + +//***************************************************************************** +//! Includes +//***************************************************************************** +#include +#include +#include + +//***************************************************************************** +//! Defines +//***************************************************************************** + +//***************************************************************************** +//! Globals +//***************************************************************************** + +static void SimpleGatt_changeCB( uint8_t paramId ); +void SimpleGatt_notifyChar4(); + +// Simple GATT Profile Callbacks +static SimpleGattProfile_CBs_t simpleGatt_profileCBs = +{ + SimpleGatt_changeCB // Simple GATT Characteristic value change callback +}; + +//***************************************************************************** +//! Functions +//***************************************************************************** + +/********************************************************************* + * @fn SimpleGatt_ChangeCB + * + * @brief Callback from Simple Profile indicating a characteristic + * value change. + * + * @param paramId - parameter Id of the value that was changed. + * + * @return None. + */ +static void SimpleGatt_changeCB( uint8_t paramId ) +{ + uint8_t newValue = 0; + + switch( paramId ) + { + case SIMPLEGATTPROFILE_CHAR1: + { + SimpleGattProfile_getParameter( SIMPLEGATTPROFILE_CHAR1, &newValue ); + + // Print the new value of char 1 + Display_printf( dispHandle, dispIndex, 0, + "#%5d Data Simple Profile Callback: Char 1 = %d", + dispIndex, newValue ); dispIndex++; + } + break; + + case SIMPLEGATTPROFILE_CHAR3: + { + SimpleGattProfile_getParameter(SIMPLEGATTPROFILE_CHAR3, &newValue); + + // Print the new value of char 3 + Display_printf( dispHandle, dispIndex, 0, + "#%5d Data Simple Profile Callback: Char 3 = %d", + dispIndex, newValue ); dispIndex++; + + SimpleGatt_notifyChar4(); + } + break; + case SIMPLEGATTPROFILE_CHAR4: + { + // Print Notification registration to user + Display_printf( dispHandle, dispIndex, 0, + "#%5d Data Simple Profile Callback: Char 4 = Notification registration", + dispIndex ); dispIndex++; + + SimpleGatt_notifyChar4(); + break; + } + default: + // should not reach here! + break; + } +} + +/********************************************************************* + * @fn SimpleGatt_start + * + * @brief This function is called after stack initialization, + * the purpose of this function is to initialize and + * register the Simple GATT profile. + * + * @return SUCCESS or stack call status + */ +bStatus_t SimpleGatt_start( void ) +{ + bStatus_t status = SUCCESS; + + // Add Simple GATT service + status = SimpleGattProfile_addService(); + if(status != SUCCESS) + { + // Return status value + return(status); + } + + // Setup the Simple GATT Characteristic Values + // For more information, see the GATT and GATTServApp sections in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + { + uint8_t charValue1 = 1; + uint8_t charValue2 = 2; + uint8_t charValue3 = 3; + uint8_t charValue4 = 4; + uint8_t charValue5[SIMPLEGATTPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 }; + + SimpleGattProfile_setParameter( SIMPLEGATTPROFILE_CHAR1, sizeof(uint8_t), + &charValue1 ); + SimpleGattProfile_setParameter( SIMPLEGATTPROFILE_CHAR2, sizeof(uint8_t), + &charValue2 ); + SimpleGattProfile_setParameter( SIMPLEGATTPROFILE_CHAR3, sizeof(uint8_t), + &charValue3 ); + SimpleGattProfile_setParameter( SIMPLEGATTPROFILE_CHAR4, sizeof(uint8_t), + &charValue4 ); + SimpleGattProfile_setParameter( SIMPLEGATTPROFILE_CHAR5, SIMPLEGATTPROFILE_CHAR5_LEN, + charValue5 ); + } + // Register callback with SimpleGATTprofile + status = SimpleGattProfile_registerAppCBs( &simpleGatt_profileCBs ); + + // Return status value + return(status); +} + +/********************************************************************* + * @fn SimpleGatt_notifyChar4 + * + * @brief This function is called when WriteReq has been received to Char 4 or to Char 3. + * The purpose of this function is to send notification of Char 3 with the value + * of Char 3. + * + * @return void + */ +void SimpleGatt_notifyChar4() +{ + uint8_t value; + if (SimpleGattProfile_getParameter(SIMPLEGATTPROFILE_CHAR3, &value) == SUCCESS) + { + // Call to set that value of the fourth characteristic in the profile. + // Note that if notifications of the fourth characteristic have been + // enabled by a GATT client device, then a notification will be sent + // every time there is a change in Char 3 or Char 4. + SimpleGattProfile_setParameter(SIMPLEGATTPROFILE_CHAR4, sizeof(uint8_t), + &value); + } +} diff --git a/examples/apps/cli/bleAppTask.c b/examples/apps/cli/bleAppTask.c new file mode 100644 index 0000000..13bf470 --- /dev/null +++ b/examples/apps/cli/bleAppTask.c @@ -0,0 +1,2608 @@ +//Check to see if BLE5-stack works on exec_core + +#include "bleAppTask.h" +#include +#include +#include +#include +#include "Logger.h" +#include "bleStackApp.h" +#include "ble_user_config.h" +#include +#include +#include "util.h" +#include "hal_assert.h" + +//Wei +//#include +#include + +//Wei +/* remove tirtos code */ +//#include +//#include +//#include +//#include + +#include + +//Wei +/* add freertos code */ +#include +#include +#include + +/*#if (!(defined __TI_COMPILER_VERSION__) && !(defined __GNUC__))*/ +#if ((!(defined FREERTOS) && !(defined __TI_COMPILER_VERSION__)) && !(defined __GNUC__)) +#include +#endif + +#include +#include + +#include +/* This Header file contains all BLE API and icall structure definition */ +#include + +#include +#include + +#ifdef USE_RCOSC +#include +#endif //USE_RCOSC + +#include +#include + +#include + +#include "bleStack_menu.h" +#include "ti_ble_config.h" + +#ifdef PTM_MODE +#include "npi_task.h" // To allow RX event registration +#include "npi_ble.h" // To enable transmission of messages to UART +#include "icall_hci_tl.h" // To allow ICall HCI Transport Layer +#endif // PTM_MODE + + +/********************************************************************* + * MACROS + */ + +/********************************************************************* + * CONSTANTS + */ +// How often to perform periodic event (in ms) +#define SP_PERIODIC_EVT_PERIOD 5000 + +// Task configuration +#define SP_TASK_PRIORITY 1 + +#ifndef SP_TASK_STACK_SIZE +#define SP_TASK_STACK_SIZE 1024 +#endif + +// Application events +#define SP_STATE_CHANGE_EVT 0 +#define SP_CHAR_CHANGE_EVT 1 +#define SP_KEY_CHANGE_EVT 2 +#define SP_ADV_EVT 3 +#define SP_PAIR_STATE_EVT 4 +#define SP_PASSCODE_EVT 5 +#define SP_PERIODIC_EVT 6 +#define SP_READ_RPA_EVT 7 +#define SP_SEND_PARAM_UPDATE_EVT 8 +#define SP_CONN_EVT 9 + +// Internal Events for RTOS application +#define SP_ICALL_EVT ICALL_MSG_EVENT_ID // Event_Id_31 +#define SP_QUEUE_EVT UTIL_QUEUE_EVENT_ID // Event_Id_30 + +// Bitwise OR of all RTOS events to pend on +#define SP_ALL_EVENTS (SP_ICALL_EVT | \ + SP_QUEUE_EVT) + +// Size of string-converted device address ("0xXXXXXXXXXXXX") +#define SP_ADDR_STR_SIZE 15 + +// Row numbers for two-button menu +#define SP_ROW_SEPARATOR_1 (TBM_ROW_APP + 0) +#define SP_ROW_STATUS_1 (TBM_ROW_APP + 1) +#define SP_ROW_STATUS_2 (TBM_ROW_APP + 2) +#define SP_ROW_CONNECTION (TBM_ROW_APP + 3) +#define SP_ROW_ADVSTATE (TBM_ROW_APP + 4) +#define SP_ROW_RSSI (TBM_ROW_APP + 5) +#define SP_ROW_IDA (TBM_ROW_APP + 6) +#define SP_ROW_RPA (TBM_ROW_APP + 7) +#define SP_ROW_DEBUG (TBM_ROW_APP + 8) +#define SP_ROW_AC (TBM_ROW_APP + 9) + +// For storing the active connections +#define SP_RSSI_TRACK_CHNLS 1 // Max possible channels can be GAP_BONDINGS_MAX +#define SP_MAX_RSSI_STORE_DEPTH 5 +#define SP_INVALID_HANDLE 0xFFFF +#define RSSI_2M_THRSHLD -30 +#define RSSI_1M_THRSHLD -40 +#define RSSI_S2_THRSHLD -50 +#define RSSI_S8_THRSHLD -60 +#define SP_PHY_NONE LL_PHY_NONE // No PHY set +#define AUTO_PHY_UPDATE 0xFF + +// Spin if the expression is not true +#define SIMPLEPERIPHERAL_ASSERT(expr) if (!(expr)) simple_peripheral_spin(); + +/********************************************************************* + * TYPEDEFS + */ + +// Auto connect availble groups +enum +{ + AUTOCONNECT_DISABLE = 0, // Disable + AUTOCONNECT_GROUP_A = 1, // Group A + AUTOCONNECT_GROUP_B = 2 // Group B +}; + + +// App event passed from stack modules. This type is defined by the application +// since it can queue events to itself however it wants. +typedef struct +{ + uint8_t event; // event type + void *pData; // pointer to message +} spEvt_t; + +// Container to store passcode data when passing from gapbondmgr callback +// to app event. See the pfnPairStateCB_t documentation from the gapbondmgr.h +// header file for more information on each parameter. +typedef struct +{ + uint8_t state; + uint16_t connHandle; + uint8_t status; +} spPairStateData_t; + +// Container to store passcode data when passing from gapbondmgr callback +// to app event. See the pfnPasscodeCB_t documentation from the gapbondmgr.h +// header file for more information on each parameter. +typedef struct +{ + uint8_t deviceAddr[B_ADDR_LEN]; + uint16_t connHandle; + uint8_t uiInputs; + uint8_t uiOutputs; + uint32_t numComparison; +} spPasscodeData_t; + +// Container to store advertising event data when passing from advertising +// callback to app event. See the respective event in GapAdvScan_Event_IDs +// in gap_advertiser.h for the type that pBuf should be cast to. +typedef struct +{ + uint32_t event; + void *pBuf; +} spGapAdvEventData_t; + +// Container to store information from clock expiration using a flexible array +// since data is not always needed +typedef struct +{ + uint8_t event; // + uint8_t data[]; +} spClockEventData_t; + +// List element for parameter update and PHY command status lists +typedef struct +{ + List_Elem elem; + uint16_t connHandle; +} spConnHandleEntry_t; + +// Connected device information +typedef struct +{ + uint16_t connHandle; // Connection Handle + spClockEventData_t* pParamUpdateEventData; + Clock_Struct* pUpdateClock; // pointer to clock struct + int8_t rssiArr[SP_MAX_RSSI_STORE_DEPTH]; + uint8_t rssiCntr; + int8_t rssiAvg; + bool phyCngRq; // Set to true if PHY change request is in progress + uint8_t currPhy; + uint8_t rqPhy; + uint8_t phyRqFailCnt; // PHY change request count + bool isAutoPHYEnable; // Flag to indicate auto phy change +} spConnRec_t; + +/********************************************************************* + * GLOBAL VARIABLES + */ +//Wei +mqd_t g_EventsQueueID; + +// Display Interface +Display_Handle dispHandle = NULL; + +// Task configuration +//Wei +//Task_Struct spTask; +#if defined __TI_COMPILER_VERSION__ +#pragma DATA_ALIGN(spTaskStack, 8) +#else +#pragma data_alignment=8 +#endif +//Wei +//uint8_t spTaskStack[SP_TASK_STACK_SIZE]; + +#define APP_EVT_EVENT_MAX 0x9 +char *appEventStrings[] = { + "APP_STATE_CHANGE_EVT ", + "APP_CHAR_CHANGE_EVT ", + "APP_KEY_CHANGE_EVT ", + "APP_ADV_EVT ", + "APP_PAIR_STATE_EVT ", + "APP_PASSCODE_EVT ", + "APP_READ_RPA_EVT ", + "APP_PERIODIC_EVT ", + "APP_SEND_PARAM_UPDATE_EVT", + "APP_CONN_EVT ", +}; + +/********************************************************************* + * LOCAL VARIABLES + */ + +// Entity ID globally used to check for source and/or destination of messages +static ICall_EntityID selfEntity; +//Wei +ICall_SyncHandle syncEvent; + +// Event globally used to post local events and pend on system and +// local events. + +//Wei +//static ICall_SyncHandle syncEvent; +mqd_t g_POSIX_appMsgQueue; + +// Queue object used for app messages +//Wei +//static Queue_Struct appMsgQueue; +static QueueHandle_t appMsgQueueHandle; + +// Clock instance for internal periodic events. Only one is needed since +// GattServApp will handle notifying all connected GATT clients +static Clock_Struct clkPeriodic; +// Clock instance for RPA read events. +static Clock_Struct clkRpaRead; + +// Memory to pass periodic event ID to clock handler +spClockEventData_t argPeriodic = +{ .event = SP_PERIODIC_EVT }; + +// Memory to pass RPA read event ID to clock handler +spClockEventData_t argRpaRead = +{ .event = SP_READ_RPA_EVT }; + +// Per-handle connection info +static spConnRec_t connList[MAX_NUM_BLE_CONNS]; + +// Current connection handle as chosen by menu +static uint16_t menuConnHandle = LINKDB_CONNHANDLE_INVALID; + +// List to store connection handles for set phy command status's +static List_List setPhyCommStatList; + +// List to store connection handles for queued param updates +static List_List paramUpdateList; + +// Auto connect Disabled/Enabled {0 - Disabled, 1- Group A , 2-Group B, ...} +uint8_t autoConnect = AUTOCONNECT_DISABLE; + +// Advertising handles +static uint8 advHandleLegacy; +static uint8 advHandleLongRange; + +// Address mode +static GAP_Addr_Modes_t addrMode = DEFAULT_ADDRESS_MODE; + +// Current Random Private Address +static uint8 rpa[B_ADDR_LEN] = {0}; + +/********************************************************************* + * LOCAL FUNCTIONS + */ + +static void SimplePeripheral_init( void ); +static void simple_peripheral_spin( void ); +//Wei +//static void SimplePeripheral_taskFxn(UArg a0, UArg a1); + +static uint8_t SimplePeripheral_processStackMsg(ICall_Hdr *pMsg); +static uint8_t SimplePeripheral_processGATTMsg(gattMsgEvent_t *pMsg); +static void SimplePeripheral_processGapMessage(gapEventHdr_t *pMsg); +static void SimplePeripheral_advCallback(uint32_t event, void *pBuf, uintptr_t arg); +static void SimplePeripheral_processAdvEvent(spGapAdvEventData_t *pEventData); +static void SimplePeripheral_processAppMsg(spEvt_t *pMsg); +static void SimplePeripheral_processCharValueChangeEvt(uint8_t paramId); +static void SimplePeripheral_performPeriodicTask(void); +static void SimplePeripheral_updateRPA(void); +//Wei +static void SimplePeripheral_clockHandler(void *arg); +//static void SimplePeripheral_clockHandler(UArg arg); +static void SimplePeripheral_passcodeCb(uint8_t *pDeviceAddr, uint16_t connHandle, + uint8_t uiInputs, uint8_t uiOutputs, + uint32_t numComparison); +static void SimplePeripheral_pairStateCb(uint16_t connHandle, uint8_t state, + uint8_t status); +static void SimplePeripheral_processPairState(spPairStateData_t *pPairState); +static void SimplePeripheral_processPasscode(spPasscodeData_t *pPasscodeData); +static void SimplePeripheral_charValueChangeCB(uint8_t paramId); +static status_t SimplePeripheral_enqueueMsg(uint8_t event, void *pData); +static void SimplePeripheral_keyChangeHandler(uint8 keys); +static void SimplePeripheral_handleKeys(uint8_t keys); +static void SimplePeripheral_processCmdCompleteEvt(hciEvt_CmdComplete_t *pMsg); +static void SimplePeripheral_initPHYRSSIArray(void); +static void SimplePeripheral_updatePHYStat(uint16_t eventCode, uint8_t *pMsg); +static uint8_t SimplePeripheral_addConn(uint16_t connHandle); +static uint8_t SimplePeripheral_getConnIndex(uint16_t connHandle); +static uint8_t SimplePeripheral_removeConn(uint16_t connHandle); +static void SimplePeripheral_processParamUpdate(uint16_t connHandle); +static status_t SimplePeripheral_startAutoPhyChange(uint16_t connHandle); +static status_t SimplePeripheral_stopAutoPhyChange(uint16_t connHandle); +static status_t SimplePeripheral_setPhy(uint16_t connHandle, uint8_t allPhys, + uint8_t txPhy, uint8_t rxPhy, + uint16_t phyOpts); +static uint8_t SimplePeripheral_clearConnListEntry(uint16_t connHandle); +static void SimplePeripheral_menuSwitchCb(tbmMenuObj_t* pMenuObjCurr, + tbmMenuObj_t* pMenuObjNext); +static void SimplePeripheral_connEvtCB(Gap_ConnEventRpt_t *pReport); +static void SimplePeripheral_processConnEvt(Gap_ConnEventRpt_t *pReport); +#ifdef PTM_MODE +void simple_peripheral_handleNPIRxInterceptEvent(uint8_t *pMsg); // Declaration +static void simple_peripheral_sendToNPI(uint8_t *buf, uint16_t len); // Declaration +#endif // PTM_MODE + +/********************************************************************* + * EXTERN FUNCTIONS + */ +extern void AssertHandler(uint8 assertCause, uint8 assertSubcause); + +/********************************************************************* + * PROFILE CALLBACKS + */ + +// GAP Bond Manager Callbacks +static gapBondCBs_t SimplePeripheral_BondMgrCBs = +{ + SimplePeripheral_passcodeCb, // Passcode callback + SimplePeripheral_pairStateCb // Pairing/Bonding state Callback +}; + +// Simple GATT Profile Callbacks +static simpleProfileCBs_t SimplePeripheral_simpleProfileCBs = +{ + SimplePeripheral_charValueChangeCB // Simple GATT Characteristic value change callback +}; + +//Citadel Application definition + + +static TaskHandle_t BLEAPPTaskHandle = NULL; + +void bleAppTask_init() +{ + RegisterAssertCback(AssertHandler); + // initialize the ICall module + ICall_init(); + + // Start tasks of external images - Priority 5 + ICall_createRemoteTasks(); + + if (xTaskCreate(BleMain, "BleMain", BLEAPP_TASK_STACK_SIZE/sizeof(StackType_t), NULL, BLEAPP_TASK_PRIORITY, &BLEAPPTaskHandle)!=pdPASS) + { + otPlatLog(OT_LOG_LEVEL_DEBG, OT_LOG_REGION_PLATFORM,"BLEAPP Failed to created\n"); + while (1) ; + } +} + +static void BleMain(void * pvParameter) +{ + //Initialize ble application + bleStack_init(); + + //ble application main loop + for (;;) + { + /* main loop for BleMain functionalities */ + { + uint32_t events; + + // Waits for an event to be posted associated with the calling thread. + // Note that an event associated with a thread is posted when a + // message is queued to the message receive queue of the thread + + //Wei + mq_receive(syncEvent, (char*)&events, sizeof(uint32_t), NULL); + //events = Event_pend(syncEvent, Event_Id_NONE, SP_ALL_EVENTS, + // ICALL_TIMEOUT_FOREVER); + + if (events) + { + ICall_EntityID dest; + ICall_ServiceEnum src; + ICall_HciExtEvt *pMsg = NULL; + + // Fetch any available messages that might have been sent from the stack + if (ICall_fetchServiceMsg(&src, &dest, + (void **)&pMsg) == ICALL_ERRNO_SUCCESS) + { + uint8 safeToDealloc = TRUE; + + if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity)) + { + ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg; + + // Check for BLE stack events first + if (pEvt->signature != 0xffff) + { + // Process inter-task message + safeToDealloc = SimplePeripheral_processStackMsg((ICall_Hdr *)pMsg); + } + } + + if (pMsg && safeToDealloc) + { + ICall_freeMsg(pMsg); + } + } + + // If RTOS queue is not empty, process app message. + if (events & SP_QUEUE_EVT) + { + //Wei + spEvt_t *pMsg; + do + { + pMsg = (spEvt_t *)Util_dequeueMsg(g_POSIX_appMsgQueue); + if (NULL != pMsg) + { + // Process message. + SimplePeripheral_processAppMsg(pMsg); + + // Free the space from the message. + ICall_free(pMsg); + } + else + { + break; + } + } while(1); +#if 0 + while (!Queue_empty(appMsgQueueHandle)) + { + spEvt_t *pMsg = (spEvt_t *)Util_dequeueMsg(appMsgQueueHandle); + if (pMsg) + { + // Process message. + SimplePeripheral_processAppMsg(pMsg); + + // Free the space from the message. + ICall_free(pMsg); + } + } +#endif + } + } + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_processStackMsg + * + * @brief Process an incoming stack message. + * + * @param pMsg - message to process + * + * @return TRUE if safe to deallocate incoming message, FALSE otherwise. + */ +static uint8_t SimplePeripheral_processStackMsg(ICall_Hdr *pMsg) +{ + // Always dealloc pMsg unless set otherwise + uint8_t safeToDealloc = TRUE; + + BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : Stack msg status=%d, event=0x%x\n", pMsg->status, pMsg->event); + + switch (pMsg->event) + { + case GAP_MSG_EVENT: + SimplePeripheral_processGapMessage((gapEventHdr_t*) pMsg); + break; + + case GATT_MSG_EVENT: + // Process GATT message + safeToDealloc = SimplePeripheral_processGATTMsg((gattMsgEvent_t *)pMsg); + break; + + case HCI_GAP_EVENT_EVENT: + { + // Process HCI message + switch(pMsg->status) + { + case HCI_COMMAND_COMPLETE_EVENT_CODE: + // Process HCI Command Complete Events here + { + SimplePeripheral_processCmdCompleteEvt((hciEvt_CmdComplete_t *) pMsg); + break; + } + + case HCI_BLE_HARDWARE_ERROR_EVENT_CODE: + AssertHandler(HAL_ASSERT_CAUSE_HARDWARE_ERROR,0); + break; + + // HCI Commands Events + case HCI_COMMAND_STATUS_EVENT_CODE: + { + hciEvt_CommandStatus_t *pMyMsg = (hciEvt_CommandStatus_t *)pMsg; + switch ( pMyMsg->cmdOpcode ) + { + case HCI_LE_SET_PHY: + { + if (pMyMsg->cmdStatus == HCI_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE) + { + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, + "PHY Change failure, peer does not support this"); + } + else + { + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, + "PHY Update Status Event: 0x%x", + pMyMsg->cmdStatus); + } + + SimplePeripheral_updatePHYStat(HCI_LE_SET_PHY, (uint8_t *)pMsg); + break; + } + + default: + break; + } + break; + } + + // LE Events + case HCI_LE_EVENT_CODE: + { + hciEvt_BLEPhyUpdateComplete_t *pPUC = + (hciEvt_BLEPhyUpdateComplete_t*) pMsg; + + // A Phy Update Has Completed or Failed + if (pPUC->BLEEventCode == HCI_BLE_PHY_UPDATE_COMPLETE_EVENT) + { + if (pPUC->status != SUCCESS) + { + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, + "PHY Change failure"); + } + else + { + // Only symmetrical PHY is supported. + // rxPhy should be equal to txPhy. + Display_printf(dispHandle, SP_ROW_STATUS_2, 0, + "PHY Updated to %s", + (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_1M) ? "1M" : + (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_2M) ? "2M" : + (pPUC->rxPhy == PHY_UPDATE_COMPLETE_EVENT_CODED) ? "CODED" : "Unexpected PHY Value"); + } + + SimplePeripheral_updatePHYStat(HCI_BLE_PHY_UPDATE_COMPLETE_EVENT, (uint8_t *)pMsg); + } + break; + } + + default: + break; + } + + break; + } + + default: + // do nothing + break; + } + +#ifdef PTM_MODE + // Check for NPI Messages + hciPacket_t *pBuf = (hciPacket_t *)pMsg; + + // Serialized HCI Event + if (pBuf->hdr.event == HCI_CTRL_TO_HOST_EVENT) + { + uint16_t len = 0; + + // Determine the packet length + switch(pBuf->pData[0]) + { + case HCI_EVENT_PACKET: + len = HCI_EVENT_MIN_LENGTH + pBuf->pData[2]; + break; + + case HCI_ACL_DATA_PACKET: + len = HCI_DATA_MIN_LENGTH + BUILD_UINT16(pBuf->pData[3], pBuf->pData[4]); + break; + + default: + break; + } + + // Send to Remote Host. + simple_peripheral_sendToNPI(pBuf->pData, len); + + // Free buffers if needed. + switch (pBuf->pData[0]) + { + case HCI_ACL_DATA_PACKET: + case HCI_SCO_DATA_PACKET: + BM_free(pBuf->pData); + default: + break; + } + } +#endif // PTM_MODE + + return (safeToDealloc); +} + +/********************************************************************* + * @fn SimplePeripheral_processGATTMsg + * + * @brief Process GATT messages and events. + * + * @return TRUE if safe to deallocate incoming message, FALSE otherwise. + */ +static uint8_t SimplePeripheral_processGATTMsg(gattMsgEvent_t *pMsg) +{ + if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT) + { + // ATT request-response or indication-confirmation flow control is + // violated. All subsequent ATT requests or indications will be dropped. + // The app is informed in case it wants to drop the connection. + + // Display the opcode of the message that caused the violation. + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "FC Violated: %d", pMsg->msg.flowCtrlEvt.opcode); + } + else if (pMsg->method == ATT_MTU_UPDATED_EVENT) + { + // MTU size updated + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "MTU Size: %d", pMsg->msg.mtuEvt.MTU); + } + + // Free message payload. Needed only for ATT Protocol messages + GATT_bm_free(&pMsg->msg, pMsg->method); + + // It's safe to free the incoming message + return (TRUE); +} + +/********************************************************************* + * @fn SimplePeripheral_processAppMsg + * + * @brief Process an incoming callback from a profile. + * + * @param pMsg - message to process + * + * @return None. + */ +static void SimplePeripheral_processAppMsg(spEvt_t *pMsg) +{ + bool dealloc = TRUE; + + if (pMsg->event <= APP_EVT_EVENT_MAX) + { + BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=%s\n", 0, appEventStrings[pMsg->event]); + } + else + { + BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : App msg status=%d, event=0x%x\n", 0, pMsg->event); + } + + switch (pMsg->event) + { + case SP_CHAR_CHANGE_EVT: + SimplePeripheral_processCharValueChangeEvt(*(uint8_t*)(pMsg->pData)); + break; + + case SP_KEY_CHANGE_EVT: + SimplePeripheral_handleKeys(*(uint8_t*)(pMsg->pData)); + break; + + case SP_ADV_EVT: + SimplePeripheral_processAdvEvent((spGapAdvEventData_t*)(pMsg->pData)); + break; + + case SP_PAIR_STATE_EVT: + SimplePeripheral_processPairState((spPairStateData_t*)(pMsg->pData)); + break; + + case SP_PASSCODE_EVT: + SimplePeripheral_processPasscode((spPasscodeData_t*)(pMsg->pData)); + break; + + case SP_PERIODIC_EVT: + SimplePeripheral_performPeriodicTask(); + break; + + case SP_READ_RPA_EVT: + SimplePeripheral_updateRPA(); + break; + + case SP_SEND_PARAM_UPDATE_EVT: + { + // Extract connection handle from data + uint16_t connHandle = *(uint16_t *)(((spClockEventData_t *)pMsg->pData)->data); + + SimplePeripheral_processParamUpdate(connHandle); + + // This data is not dynamically allocated + dealloc = FALSE; + break; + } + + case SP_CONN_EVT: + SimplePeripheral_processConnEvt((Gap_ConnEventRpt_t *)(pMsg->pData)); + break; + + default: + // Do nothing. + break; + } + + // Free message data if it exists and we are to dealloc + if ((dealloc == TRUE) && (pMsg->pData != NULL)) + { + ICall_free(pMsg->pData); + } +} + +/********************************************************************* + * @fn SimplePeripheral_processGapMessage + * + * @brief Process an incoming GAP event. + * + * @param pMsg - message to process + */ +static void SimplePeripheral_processGapMessage(gapEventHdr_t *pMsg) +{ + switch(pMsg->opcode) + { + case GAP_DEVICE_INIT_DONE_EVENT: + { + bStatus_t status = FAILURE; + + gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg; + + if(pPkt->hdr.status == SUCCESS) + { + // Store the system ID + uint8_t systemId[DEVINFO_SYSTEM_ID_LEN]; + + // use 6 bytes of device address for 8 bytes of system ID value + systemId[0] = pPkt->devAddr[0]; + systemId[1] = pPkt->devAddr[1]; + systemId[2] = pPkt->devAddr[2]; + + // set middle bytes to zero + systemId[4] = 0x00; + systemId[3] = 0x00; + + // shift three bytes up + systemId[7] = pPkt->devAddr[5]; + systemId[6] = pPkt->devAddr[4]; + systemId[5] = pPkt->devAddr[3]; + + // Set Device Info Service Parameter + DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId); + + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Initialized"); + + BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- got GAP_DEVICE_INIT_DONE_EVENT", 0); + // Setup and start Advertising + // For more information, see the GAP section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + + BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : ---- call GapAdv_create set=%d,%d\n", 0, 0); + // Create Advertisement set #1 and assign handle + status = GapAdv_create(&SimplePeripheral_advCallback, &advParams1, &advHandleLegacy); + //Wei + if ( status != SUCCESS ) + { + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Failed to create the GAP Adv (%d:0x%02x)", status, status); + vTaskDelay(pdMS_TO_TICKS(500)); + } + SIMPLEPERIPHERAL_ASSERT(status == SUCCESS); + + // Load advertising data for set #1 that is statically allocated by the app + //Wei + status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_ADV, + sizeof(advData1), advData1); + //Wei + SIMPLEPERIPHERAL_ASSERT(status == SUCCESS); + + // Load scan response data for set #1 that is statically allocated by the app + status = GapAdv_loadByHandle(advHandleLegacy, GAP_ADV_DATA_TYPE_SCAN_RSP, + sizeof(scanResData1), scanResData1); + SIMPLEPERIPHERAL_ASSERT(status == SUCCESS); + + // Set event mask for set #1 + status = GapAdv_setEventMask(advHandleLegacy, + GAP_ADV_EVT_MASK_START_AFTER_ENABLE | + GAP_ADV_EVT_MASK_END_AFTER_DISABLE | + GAP_ADV_EVT_MASK_SET_TERMINATED); + + // Enable legacy advertising for set #1 + status = GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + //Wei + SIMPLEPERIPHERAL_ASSERT(status == SUCCESS); + + BLE_LOG_INT_INT(0, BLE_LOG_MODULE_APP, "APP : ---- call GapAdv_create set=%d,%d\n", 1, 0); + // Create Advertisement set #2 and assign handle + status = GapAdv_create(&SimplePeripheral_advCallback, &advParams2, + &advHandleLongRange); + //Wei + SIMPLEPERIPHERAL_ASSERT(status == SUCCESS); + + // Load advertising data for set #2 that is statically allocated by the app + status = GapAdv_loadByHandle(advHandleLongRange, GAP_ADV_DATA_TYPE_ADV, + sizeof(advData2), advData2); + //Wei + SIMPLEPERIPHERAL_ASSERT(status == SUCCESS); + + // Set event mask for set #2 + status = GapAdv_setEventMask(advHandleLongRange, + GAP_ADV_EVT_MASK_START_AFTER_ENABLE | + GAP_ADV_EVT_MASK_END_AFTER_DISABLE | + GAP_ADV_EVT_MASK_SET_TERMINATED); + + BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- GapAdv_enable", 0); + // Enable long range advertising for set #2 + status = GapAdv_enable(advHandleLongRange, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + //Wei + SIMPLEPERIPHERAL_ASSERT(status == SUCCESS); + + // Display device address + Display_printf(dispHandle, SP_ROW_IDA, 0, "%s Addr: %s", + (addrMode <= ADDRMODE_RANDOM) ? "Dev" : "ID", + Util_convertBdAddr2Str(pPkt->devAddr)); + + if (addrMode > ADDRMODE_RANDOM) + { + SimplePeripheral_updateRPA(); + + // Create one-shot clock for RPA check event. + //Wei + + Util_constructClock(&clkRpaRead,(void*)SimplePeripheral_clockHandler, READ_RPA_PERIOD, 0, true, (uint32_t)&argRpaRead); + // Util_constructClock(&clkRpaRead, SimplePeripheral_clockHandler, + // READ_RPA_PERIOD, 0, true, + // (void *)&argRpaRead); + } + tbm_setItemStatus(&spMenuMain, SP_ITEM_AUTOCONNECT, TBM_ITEM_NONE); + } + + break; + } + + case GAP_LINK_ESTABLISHED_EVENT: + { + gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg; + + BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- got GAP_LINK_ESTABLISHED_EVENT", 0); + // Display the amount of current connections + uint8_t numActive = linkDB_NumActive(); + Display_printf(dispHandle, SP_ROW_STATUS_2, 0, "Num Conns: %d", + (uint16_t)numActive); + + if (pPkt->hdr.status == SUCCESS) + { + // Add connection to list and start RSSI + SimplePeripheral_addConn(pPkt->connectionHandle); + + // Display the address of this connection + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Connected to %s", + Util_convertBdAddr2Str(pPkt->devAddr)); + + // Enable connection selection option + tbm_setItemStatus(&spMenuMain, SP_ITEM_SELECT_CONN,SP_ITEM_AUTOCONNECT); + + // Start Periodic Clock. + Util_startClock(&clkPeriodic); + } + if ((numActive < MAX_NUM_BLE_CONNS) && (autoConnect == AUTOCONNECT_DISABLE)) + { + // Start advertising since there is room for more connections + GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + GapAdv_enable(advHandleLongRange, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + } + else + { + // Stop advertising since there is no room for more connections + GapAdv_disable(advHandleLongRange); + GapAdv_disable(advHandleLegacy); + } + break; + } + + case GAP_LINK_TERMINATED_EVENT: + { + gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg; + + // Display the amount of current connections + uint8_t numActive = linkDB_NumActive(); + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Device Disconnected!"); + Display_printf(dispHandle, SP_ROW_STATUS_2, 0, "Num Conns: %d", + (uint16_t)numActive); + + // Remove the connection from the list and disable RSSI if needed + SimplePeripheral_removeConn(pPkt->connectionHandle); + + // If no active connections + if (numActive == 0) + { + // Stop periodic clock + Util_stopClock(&clkPeriodic); + + // Disable Connection Selection option + tbm_setItemStatus(&spMenuMain, SP_ITEM_AUTOCONNECT, SP_ITEM_SELECT_CONN); + } + + BLE_LOG_INT_STR(0, BLE_LOG_MODULE_APP, "APP : GAP msg: status=%d, opcode=%s\n", 0, "GAP_LINK_TERMINATED_EVENT"); + // Start advertising since there is room for more connections + GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + GapAdv_enable(advHandleLongRange, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + + // Clear remaining lines + Display_clearLine(dispHandle, SP_ROW_CONNECTION); + + break; + } + + case GAP_UPDATE_LINK_PARAM_REQ_EVENT: + { + gapUpdateLinkParamReqReply_t rsp; + + gapUpdateLinkParamReqEvent_t *pReq = (gapUpdateLinkParamReqEvent_t *)pMsg; + + rsp.connectionHandle = pReq->req.connectionHandle; + rsp.signalIdentifier = pReq->req.signalIdentifier; + + // Only accept connection intervals with slave latency of 0 + // This is just an example of how the application can send a response + if(pReq->req.connLatency == 0) + { + rsp.intervalMin = pReq->req.intervalMin; + rsp.intervalMax = pReq->req.intervalMax; + rsp.connLatency = pReq->req.connLatency; + rsp.connTimeout = pReq->req.connTimeout; + rsp.accepted = TRUE; + } + else + { + rsp.accepted = FALSE; + } + + // Send Reply + VOID GAP_UpdateLinkParamReqReply(&rsp); + + break; + } + + case GAP_LINK_PARAM_UPDATE_EVENT: + { + gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg; + + // Get the address from the connection handle + linkDBInfo_t linkInfo; + linkDB_GetInfo(pPkt->connectionHandle, &linkInfo); + + if(pPkt->status == SUCCESS) + { + // Display the address of the connection update + Display_printf(dispHandle, SP_ROW_STATUS_2, 0, "Link Param Updated: %s", + Util_convertBdAddr2Str(linkInfo.addr)); + } + else + { + // Display the address of the connection update failure + Display_printf(dispHandle, SP_ROW_STATUS_2, 0, + "Link Param Update Failed 0x%x: %s", pPkt->opcode, + Util_convertBdAddr2Str(linkInfo.addr)); + } + + // Check if there are any queued parameter updates + spConnHandleEntry_t *connHandleEntry = (spConnHandleEntry_t *)List_get(¶mUpdateList); + if (connHandleEntry != NULL) + { + // Attempt to send queued update now + SimplePeripheral_processParamUpdate(connHandleEntry->connHandle); + + // Free list element + ICall_free(connHandleEntry); + } + + break; + } + +#if defined ( NOTIFY_PARAM_UPDATE_RJCT ) + case GAP_LINK_PARAM_UPDATE_REJECT_EVENT: + { + linkDBInfo_t linkInfo; + gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg; + + // Get the address from the connection handle + linkDB_GetInfo(pPkt->connectionHandle, &linkInfo); + + // Display the address of the connection update failure + Display_printf(dispHandle, SP_ROW_STATUS_2, 0, + "Peer Device's Update Request Rejected 0x%x: %s", pPkt->opcode, + Util_convertBdAddr2Str(linkInfo.addr)); + + break; + } +#endif + + default: + Display_clearLines(dispHandle, SP_ROW_STATUS_1, SP_ROW_STATUS_2); + break; + } +} + +/********************************************************************* + * @fn SimplePeripheral_charValueChangeCB + * + * @brief Callback from Simple Profile indicating a characteristic + * value change. + * + * @param paramId - parameter Id of the value that was changed. + * + * @return None. + */ +static void SimplePeripheral_charValueChangeCB(uint8_t paramId) +{ + uint8_t *pValue = ICall_malloc(sizeof(uint8_t)); + + if (pValue) + { + *pValue = paramId; + + if (SimplePeripheral_enqueueMsg(SP_CHAR_CHANGE_EVT, pValue) != SUCCESS) + { + ICall_free(pValue); + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_processCharValueChangeEvt + * + * @brief Process a pending Simple Profile characteristic value change + * event. + * + * @param paramID - parameter ID of the value that was changed. + */ +static void SimplePeripheral_processCharValueChangeEvt(uint8_t paramId) +{ + uint8_t newValue; + + switch(paramId) + { + case SIMPLEPROFILE_CHAR1: + SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR1, &newValue); + + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Char 1: %d", (uint16_t)newValue); + break; + + case SIMPLEPROFILE_CHAR3: + SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &newValue); + + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Char 3: %d", (uint16_t)newValue); + break; + + default: + // should not reach here! + break; + } +} + +/********************************************************************* + * @fn SimplePeripheral_performPeriodicTask + * + * @brief Perform a periodic application task. This function gets called + * every five seconds (SP_PERIODIC_EVT_PERIOD). In this example, + * the value of the third characteristic in the SimpleGATTProfile + * service is retrieved from the profile, and then copied into the + * value of the the fourth characteristic. + * + * @param None. + * + * @return None. + */ +static void SimplePeripheral_performPeriodicTask(void) +{ + uint8_t valueToCopy; + + // Call to retrieve the value of the third characteristic in the profile + if (SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR3, &valueToCopy) == SUCCESS) + { + // Call to set that value of the fourth characteristic in the profile. + // Note that if notifications of the fourth characteristic have been + // enabled by a GATT client device, then a notification will be sent + // every time this function is called. + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t), + &valueToCopy); + } +} + +/********************************************************************* + * @fn SimplePeripheral_updateRPA + * + * @brief Read the current RPA from the stack and update display + * if the RPA has changed. + * + * @param None. + * + * @return None. + */ +static void SimplePeripheral_updateRPA(void) +{ + uint8_t* pRpaNew; + + // Read the current RPA. + pRpaNew = GAP_GetDevAddress(FALSE); + + if (memcmp(pRpaNew, rpa, B_ADDR_LEN)) + { + // If the RPA has changed, update the display + Display_printf(dispHandle, SP_ROW_RPA, 0, "RP Addr: %s", + Util_convertBdAddr2Str(pRpaNew)); + memcpy(rpa, pRpaNew, B_ADDR_LEN); + } +} + +/********************************************************************* + * @fn SimplePeripheral_clockHandler + * + * @brief Handler function for clock timeouts. + * + * @param arg - event type + * + * @return None. + */ + //Wei +static void SimplePeripheral_clockHandler(void *arg) +{ + spClockEventData_t *pData = (spClockEventData_t *)arg; + + if (pData->event == SP_PERIODIC_EVT) + { + // Start the next period + Util_startClock(&clkPeriodic); + + // Post event to wake up the application + SimplePeripheral_enqueueMsg(SP_PERIODIC_EVT, NULL); + } + else if (pData->event == SP_READ_RPA_EVT) + { + // Start the next period + Util_startClock(&clkRpaRead); + + // Post event to read the current RPA + SimplePeripheral_enqueueMsg(SP_READ_RPA_EVT, NULL); + } + else if (pData->event == SP_SEND_PARAM_UPDATE_EVT) + { + // Send message to app + SimplePeripheral_enqueueMsg(SP_SEND_PARAM_UPDATE_EVT, pData); + } +} + +/********************************************************************* + * @fn SimplePeripheral_keyChangeHandler + * + * @brief Key event handler function + * + * @param keys - bitmap of pressed keys + * + * @return none + */ +static void SimplePeripheral_keyChangeHandler(uint8_t keys) +{ + uint8_t *pValue = ICall_malloc(sizeof(uint8_t)); + + if (pValue) + { + *pValue = keys; + + if(SimplePeripheral_enqueueMsg(SP_KEY_CHANGE_EVT, pValue) != SUCCESS) + { + ICall_free(pValue); + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_handleKeys + * + * @brief Handles all key events for this device. + * + * @param keys - bit field for key events. Valid entries: + * KEY_LEFT + * KEY_RIGHT + */ +static void SimplePeripheral_handleKeys(uint8_t keys) +{ + if (keys & KEY_LEFT) + { + // Check if the key is still pressed. Workaround for possible bouncing. + if (GPIO_read(CONFIG_GPIO_BTN1) == 0) + { + tbm_buttonLeft(); + } + } + else if (keys & KEY_RIGHT) + { + // Check if the key is still pressed. Workaround for possible bouncing. + if (GPIO_read(CONFIG_GPIO_BTN2) == 0) + { + tbm_buttonRight(); + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_doSetConnPhy + * + * @brief Set PHY preference. + * + * @param index - 0: 1M PHY + * 1: 2M PHY + * 2: 1M + 2M PHY + * 3: CODED PHY (Long range) + * 4: 1M + 2M + CODED PHY + * + * @return always true + */ +bool SimplePeripheral_doSetConnPhy(uint8 index) +{ + bool status = TRUE; + + static uint8_t phy[] = { + HCI_PHY_1_MBPS, HCI_PHY_2_MBPS, HCI_PHY_1_MBPS | HCI_PHY_2_MBPS, + HCI_PHY_CODED, HCI_PHY_1_MBPS | HCI_PHY_2_MBPS | HCI_PHY_CODED, + AUTO_PHY_UPDATE + }; + + uint8_t connIndex = SimplePeripheral_getConnIndex(menuConnHandle); + if (connIndex >= MAX_NUM_BLE_CONNS) + { + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Connection handle is not in the connList !!!"); + return FALSE; + } + + // Set Phy Preference on the current connection. Apply the same value + // for RX and TX. + // If auto PHY update is not selected and if auto PHY update is enabled, then + // stop auto PHY update + // Note PHYs are already enabled by default in build_config.opt in stack project. + if(phy[index] != AUTO_PHY_UPDATE) + { + // Cancel RSSI reading and auto phy changing + SimplePeripheral_stopAutoPhyChange(connList[connIndex].connHandle); + + SimplePeripheral_setPhy(menuConnHandle, 0, phy[index], phy[index], 0); + + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "PHY preference: %s", + TBM_GET_ACTION_DESC(&spMenuConnPhy, index)); + } + else + { + // Start RSSI read for auto PHY update (if it is disabled) + SimplePeripheral_startAutoPhyChange(menuConnHandle); + } + + return status; +} +/********************************************************************* + * @fn SimplePeripheral_advCallback + * + * @brief GapAdv module callback + * + * @param pMsg - message to process + */ +static void SimplePeripheral_advCallback(uint32_t event, void *pBuf, uintptr_t arg) +{ + spGapAdvEventData_t *pData = ICall_malloc(sizeof(spGapAdvEventData_t)); + + if (pData) + { + pData->event = event; + pData->pBuf = pBuf; + + if(SimplePeripheral_enqueueMsg(SP_ADV_EVT, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_processAdvEvent + * + * @brief Process advertising event in app context + * + * @param pEventData + */ +static void SimplePeripheral_processAdvEvent(spGapAdvEventData_t *pEventData) +{ + switch (pEventData->event) + { + case GAP_EVT_ADV_START_AFTER_ENABLE: + BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- GAP_EVT_ADV_START_AFTER_ENABLE", 0); + Display_printf(dispHandle, SP_ROW_ADVSTATE, 0, "Adv Set %d Enabled", + *(uint8_t *)(pEventData->pBuf)); + break; + + case GAP_EVT_ADV_END_AFTER_DISABLE: + Display_doPrintf(dispHandle, SP_ROW_ADVSTATE, 0, "Adv Set %d Disabled", + *(uint8_t *)(pEventData->pBuf)); + break; + + case GAP_EVT_ADV_START: + break; + + case GAP_EVT_ADV_END: + break; + + case GAP_EVT_ADV_SET_TERMINATED: + { +#ifndef Display_DISABLE_ALL + GapAdv_setTerm_t *advSetTerm = (GapAdv_setTerm_t *)(pEventData->pBuf); + + Display_printf(dispHandle, SP_ROW_ADVSTATE, 0, "Adv Set %d disabled after conn %d", + advSetTerm->handle, advSetTerm->connHandle ); +#endif + } + break; + + case GAP_EVT_SCAN_REQ_RECEIVED: + break; + + case GAP_EVT_INSUFFICIENT_MEMORY: + break; + + default: + break; + } + + // All events have associated memory to free except the insufficient memory + // event + if (pEventData->event != GAP_EVT_INSUFFICIENT_MEMORY) + { + ICall_free(pEventData->pBuf); + } +} + + +/********************************************************************* + * @fn SimplePeripheral_pairStateCb + * + * @brief Pairing state callback. + * + * @return none + */ +static void SimplePeripheral_pairStateCb(uint16_t connHandle, uint8_t state, + uint8_t status) +{ + spPairStateData_t *pData = ICall_malloc(sizeof(spPairStateData_t)); + + // Allocate space for the event data. + if (pData) + { + pData->state = state; + pData->connHandle = connHandle; + pData->status = status; + + // Queue the event. + if(SimplePeripheral_enqueueMsg(SP_PAIR_STATE_EVT, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_passcodeCb + * + * @brief Passcode callback. + * + * @return none + */ +static void SimplePeripheral_passcodeCb(uint8_t *pDeviceAddr, + uint16_t connHandle, + uint8_t uiInputs, + uint8_t uiOutputs, + uint32_t numComparison) +{ + spPasscodeData_t *pData = ICall_malloc(sizeof(spPasscodeData_t)); + + // Allocate space for the passcode event. + if (pData ) + { + pData->connHandle = connHandle; + memcpy(pData->deviceAddr, pDeviceAddr, B_ADDR_LEN); + pData->uiInputs = uiInputs; + pData->uiOutputs = uiOutputs; + pData->numComparison = numComparison; + + // Enqueue the event. + if(SimplePeripheral_enqueueMsg(SP_PASSCODE_EVT, pData) != SUCCESS) + { + ICall_free(pData); + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_processPairState + * + * @brief Process the new paring state. + * + * @return none + */ +static void SimplePeripheral_processPairState(spPairStateData_t *pPairData) +{ + uint8_t state = pPairData->state; + uint8_t status = pPairData->status; + + switch (state) + { + case GAPBOND_PAIRING_STATE_STARTED: + Display_printf(dispHandle, SP_ROW_CONNECTION, 0, "Pairing started"); + break; + + case GAPBOND_PAIRING_STATE_COMPLETE: + if (status == SUCCESS) + { + Display_printf(dispHandle, SP_ROW_CONNECTION, 0, "Pairing success"); + } + else + { + Display_printf(dispHandle, SP_ROW_CONNECTION, 0, "Pairing fail: %d", status); + } + break; + + case GAPBOND_PAIRING_STATE_ENCRYPTED: + if (status == SUCCESS) + { + Display_printf(dispHandle, SP_ROW_CONNECTION, 0, "Encryption success"); + } + else + { + Display_printf(dispHandle, SP_ROW_CONNECTION, 0, "Encryption failed: %d", status); + } + break; + + case GAPBOND_PAIRING_STATE_BOND_SAVED: + if (status == SUCCESS) + { + Display_printf(dispHandle, SP_ROW_CONNECTION, 0, "Bond save success"); + } + else + { + Display_printf(dispHandle, SP_ROW_CONNECTION, 0, "Bond save failed: %d", status); + } + break; + + default: + break; + } +} + +/********************************************************************* + * @fn SimplePeripheral_processPasscode + * + * @brief Process the Passcode request. + * + * @return none + */ +static void SimplePeripheral_processPasscode(spPasscodeData_t *pPasscodeData) +{ + // Display passcode to user + if (pPasscodeData->uiOutputs != 0) + { + Display_doPrintf(dispHandle, SP_ROW_CONNECTION, 0, "Passcode: %d", + B_APP_DEFAULT_PASSCODE); + } + + // Send passcode response + GAPBondMgr_PasscodeRsp(pPasscodeData->connHandle , SUCCESS, + B_APP_DEFAULT_PASSCODE); +} + +/********************************************************************* + * @fn SimplePeripheral_connEvtCB + * + * @brief Connection event callback. + * + * @param pReport pointer to connection event report + */ +static void SimplePeripheral_connEvtCB(Gap_ConnEventRpt_t *pReport) +{ + // Enqueue the event for processing in the app context. + if(SimplePeripheral_enqueueMsg(SP_CONN_EVT, pReport) != SUCCESS) + { + ICall_free(pReport); + } +} + +/********************************************************************* + * @fn SimplePeripheral_processConnEvt + * + * @brief Process connection event. + * + * @param pReport pointer to connection event report + */ +static void SimplePeripheral_processConnEvt(Gap_ConnEventRpt_t *pReport) +{ + // Get index from handle + uint8_t connIndex = SimplePeripheral_getConnIndex(pReport->handle); + + if (connIndex >= MAX_NUM_BLE_CONNS) + { + Display_doPrintf(dispHandle, SP_ROW_STATUS_1, 0, "Connection handle is not in the connList !!!"); + return; + } + + // If auto phy change is enabled + if (connList[connIndex].isAutoPHYEnable == TRUE) + { + // Read the RSSI + HCI_ReadRssiCmd(pReport->handle); + } +} + + +/********************************************************************* + * @fn SimplePeripheral_enqueueMsg + * + * @brief Creates a message and puts the message in RTOS queue. + * + * @param event - message event. + * @param state - message state. + */ +static status_t SimplePeripheral_enqueueMsg(uint8_t event, void *pData) +{ + uint8_t success; + spEvt_t *pMsg = ICall_malloc(sizeof(spEvt_t)); + + // Create dynamic pointer to message. + if(pMsg) + { + pMsg->event = event; + pMsg->pData = pData; + + // Enqueue the message. + success = Util_enqueueMsg(g_POSIX_appMsgQueue, syncEvent, (uint8_t *)pMsg); + return (success) ? SUCCESS : FAILURE; + } + + return(bleMemAllocError); +} + +/********************************************************************* + * @fn SimplePeripheral_doSelectConn + * + * @brief Select a connection to communicate with + * + * @param index - item index from the menu + * + * @return always true + */ +bool SimplePeripheral_doSelectConn(uint8_t index) +{ + menuConnHandle = connList[index].connHandle; + + // Set the menu title and go to this connection's context + TBM_SET_TITLE(&spMenuPerConn, TBM_GET_ACTION_DESC(&spMenuSelectConn, index)); + + // Clear non-connection-related message + Display_clearLine(dispHandle, SP_ROW_CONNECTION); + + tbm_goTo(&spMenuPerConn); + + return (true); +} +/********************************************************************* + * @fn SimplePeripheral_doAutoConnect + * + * @brief Enable/Disable peripheral as AutoConnect node. + * + * @param index - 0 : Disable AutoConnect + * 1 : Enable Group A + * 2 : Enable Group B + * + * @return always true + */ +bool SimplePeripheral_doAutoConnect(uint8_t index) +{ + if (index == 1) + { + if (autoConnect != AUTOCONNECT_GROUP_A) + { + GapAdv_disable(advHandleLongRange); + GapAdv_disable(advHandleLegacy); + advData1[2] = 'G'; + advData1[3] = 'A'; + advData2[2] = 'G'; + advData2[3] = 'A'; + GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + GapAdv_enable(advHandleLongRange, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + autoConnect = AUTOCONNECT_GROUP_A; + } + Display_printf(dispHandle, SP_ROW_AC, 0, "AutoConnect enabled: Group A"); + } + else if (index == 2) + { + if (autoConnect != AUTOCONNECT_GROUP_B) + { + GapAdv_disable(advHandleLongRange); + GapAdv_disable(advHandleLegacy); + advData1[2] = 'G'; + advData1[3] = 'B'; + advData2[2] = 'G'; + advData2[3] = 'B'; + GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + GapAdv_enable(advHandleLongRange, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + autoConnect = AUTOCONNECT_GROUP_B; + } + Display_printf(dispHandle, SP_ROW_AC, 0, "AutoConnect enabled: Group B"); + } + else + { + if (autoConnect) + { + GapAdv_disable(advHandleLongRange); + GapAdv_disable(advHandleLegacy); + advData1[2] = 'S'; + advData1[3] = 'P'; + advData2[2] = 'S'; + advData2[3] = 'P'; + GapAdv_enable(advHandleLegacy, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + GapAdv_enable(advHandleLongRange, GAP_ADV_ENABLE_OPTIONS_USE_MAX , 0); + autoConnect = AUTOCONNECT_DISABLE; + } + Display_printf(dispHandle, SP_ROW_AC, 0, "AutoConnect disabled"); + } + tbm_goTo(&spMenuMain); + + return (true); +} + + +/********************************************************************* + * @fn SimplePeripheral_addConn + * + * @brief Add a device to the connected device list + * + * @return index of the connected device list entry where the new connection + * info is put in. + * if there is no room, MAX_NUM_BLE_CONNS will be returned. + */ +static uint8_t SimplePeripheral_addConn(uint16_t connHandle) +{ + uint8_t i; + uint8_t status = bleNoResources; + + // Try to find an available entry + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle == LINKDB_CONNHANDLE_INVALID) + { + // Found available entry to put a new connection info in + connList[i].connHandle = connHandle; + +#ifdef DEFAULT_SEND_PARAM_UPDATE_REQ + // Allocate data to send through clock handler + connList[i].pParamUpdateEventData = ICall_malloc(sizeof(spClockEventData_t) + + sizeof (uint16_t)); + if(connList[i].pParamUpdateEventData) + { + connList[i].pParamUpdateEventData->event = SP_SEND_PARAM_UPDATE_EVT; + *((uint16_t *)connList[i].pParamUpdateEventData->data) = connHandle; + + // Create a clock object and start + connList[i].pUpdateClock + = (Clock_Struct*) ICall_malloc(sizeof(Clock_Struct)); + + if (connList[i].pUpdateClock) + { + //Wei + Util_constructClock(connList[i].pUpdateClock, + (void *)SimplePeripheral_clockHandler, + SEND_PARAM_UPDATE_DELAY, 0, true, + (uint32_t)&connList[i].pParamUpdateEventData); + } + else + { + ICall_free(connList[i].pParamUpdateEventData); + } + } + else + { + status = bleMemAllocError; + } +#endif + + // Set default PHY to 1M + connList[i].currPhy = HCI_PHY_1_MBPS; + + break; + } + } + + return status; +} + +/********************************************************************* + * @fn SimplePeripheral_getConnIndex + * + * @brief Find index in the connected device list by connHandle + * + * @return the index of the entry that has the given connection handle. + * if there is no match, MAX_NUM_BLE_CONNS will be returned. + */ +static uint8_t SimplePeripheral_getConnIndex(uint16_t connHandle) +{ + uint8_t i; + + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle == connHandle) + { + return i; + } + } + + return(MAX_NUM_BLE_CONNS); +} + +/********************************************************************* + * @fn SimplePeripheral_getConnIndex + * + * @brief Find index in the connected device list by connHandle + * + * @return SUCCESS if connHandle found valid index or bleInvalidRange + * if index wasn't found. LINKDB_CONNHANDLE_ALL will always succeed. + */ +static uint8_t SimplePeripheral_clearConnListEntry(uint16_t connHandle) +{ + uint8_t i; + // Set to invalid connection index initially + uint8_t connIndex = MAX_NUM_BLE_CONNS; + + if(connHandle != LINKDB_CONNHANDLE_ALL) + { + // Get connection index from handle + connIndex = SimplePeripheral_getConnIndex(connHandle); + if(connIndex >= MAX_NUM_BLE_CONNS) + { + return(bleInvalidRange); + } + } + + // Clear specific handle or all handles + for(i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if((connIndex == i) || (connHandle == LINKDB_CONNHANDLE_ALL)) + { + connList[i].connHandle = LINKDB_CONNHANDLE_INVALID; + connList[i].currPhy = 0; + connList[i].phyCngRq = 0; + connList[i].phyRqFailCnt = 0; + connList[i].rqPhy = 0; + memset(connList[i].rssiArr, 0, SP_MAX_RSSI_STORE_DEPTH); + connList[i].rssiAvg = 0; + connList[i].rssiCntr = 0; + connList[i].isAutoPHYEnable = FALSE; + } + } + + return(SUCCESS); +} + +/********************************************************************* + * @fn SimplePeripheral_clearPendingParamUpdate + * + * @brief clean pending param update request in the paramUpdateList list + * + * @param connHandle - connection handle to clean + * + * @return none + */ +void SimplePeripheral_clearPendingParamUpdate(uint16_t connHandle) +{ + List_Elem *curr; + + for (curr = List_head(¶mUpdateList); curr != NULL; curr = List_next(curr)) + { + if (((spConnHandleEntry_t *)curr)->connHandle == connHandle) + { + List_remove(¶mUpdateList, curr); + } + } +} + +/********************************************************************* + * @fn SimplePeripheral_removeConn + * + * @brief Remove a device from the connected device list + * + * @return index of the connected device list entry where the new connection + * info is removed from. + * if connHandle is not found, MAX_NUM_BLE_CONNS will be returned. + */ +static uint8_t SimplePeripheral_removeConn(uint16_t connHandle) +{ + uint8_t connIndex = SimplePeripheral_getConnIndex(connHandle); + + if(connIndex != MAX_NUM_BLE_CONNS) + { + Clock_Struct* pUpdateClock = connList[connIndex].pUpdateClock; + + if (pUpdateClock != NULL) + { + // Stop and destruct the RTOS clock if it's still alive + if (Util_isActive(pUpdateClock)) + { + Util_stopClock(pUpdateClock); + } + + // Destruct the clock object + Clock_destruct(pUpdateClock); + // Free clock struct + ICall_free(pUpdateClock); + // Free ParamUpdateEventData + ICall_free(connList[connIndex].pParamUpdateEventData); + } + // Clear pending update requests from paramUpdateList + SimplePeripheral_clearPendingParamUpdate(connHandle); + // Stop Auto PHY Change + SimplePeripheral_stopAutoPhyChange(connHandle); + // Clear Connection List Entry + SimplePeripheral_clearConnListEntry(connHandle); + } + + return connIndex; +} + +/********************************************************************* + * @fn SimplePeripheral_processParamUpdate + * + * @brief Process a parameters update request + * + * @return None + */ +static void SimplePeripheral_processParamUpdate(uint16_t connHandle) +{ + gapUpdateLinkParamReq_t req; + uint8_t connIndex; + + req.connectionHandle = connHandle; +#ifdef DEFAULT_SEND_PARAM_UPDATE_REQ + req.connLatency = DEFAULT_DESIRED_SLAVE_LATENCY; + req.connTimeout = DEFAULT_DESIRED_CONN_TIMEOUT; + req.intervalMin = DEFAULT_DESIRED_MIN_CONN_INTERVAL; + req.intervalMax = DEFAULT_DESIRED_MAX_CONN_INTERVAL; +#endif + + connIndex = SimplePeripheral_getConnIndex(connHandle); + if (connIndex >= MAX_NUM_BLE_CONNS) + { + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Connection handle is not in the connList !!!"); + return; + } + + // Deconstruct the clock object + Clock_destruct(connList[connIndex].pUpdateClock); + // Free clock struct, only in case it is not NULL + if (connList[connIndex].pUpdateClock != NULL) + { + ICall_free(connList[connIndex].pUpdateClock); + connList[connIndex].pUpdateClock = NULL; + } + // Free ParamUpdateEventData, only in case it is not NULL + if (connList[connIndex].pParamUpdateEventData != NULL) + ICall_free(connList[connIndex].pParamUpdateEventData); + + // Send parameter update + bStatus_t status = GAP_UpdateLinkParamReq(&req); + + // If there is an ongoing update, queue this for when the udpate completes + if (status == bleAlreadyInRequestedMode) + { + spConnHandleEntry_t *connHandleEntry = ICall_malloc(sizeof(spConnHandleEntry_t)); + if (connHandleEntry) + { + connHandleEntry->connHandle = connHandle; + + List_put(¶mUpdateList, (List_Elem *)connHandleEntry); + } + } +} + +/********************************************************************* + * @fn SimpleCentral_processCmdCompleteEvt + * + * @brief Process an incoming OSAL HCI Command Complete Event. + * + * @param pMsg - message to process + * + * @return none + */ +static void SimplePeripheral_processCmdCompleteEvt(hciEvt_CmdComplete_t *pMsg) +{ + uint8_t status = pMsg->pReturnParam[0]; + + //Find which command this command complete is for + switch (pMsg->cmdOpcode) + { + case HCI_READ_RSSI: + { + int8 rssi = (int8)pMsg->pReturnParam[3]; + + // Display RSSI value, if RSSI is higher than threshold, change to faster PHY + if (status == SUCCESS) + { + uint16_t handle = BUILD_UINT16(pMsg->pReturnParam[1], pMsg->pReturnParam[2]); + + uint8_t index = SimplePeripheral_getConnIndex(handle); + if (index >= MAX_NUM_BLE_CONNS) + { + Display_printf(dispHandle, SP_ROW_STATUS_1, 0, "Connection handle is not in the connList !!!"); + return; + } + + if (rssi != LL_RSSI_NOT_AVAILABLE) + { + connList[index].rssiArr[connList[index].rssiCntr++] = rssi; + connList[index].rssiCntr %= SP_MAX_RSSI_STORE_DEPTH; + + int16_t sum_rssi = 0; + for(uint8_t cnt=0; cnt= RSSI_2M_THRSHLD) && + (connList[index].currPhy != HCI_PHY_2_MBPS) && + (connList[index].currPhy != SP_PHY_NONE)) + { + // try to go to higher data rate + phyRqS = phyRq = HCI_PHY_2_MBPS; + } + else if((connList[index].rssiAvg < RSSI_2M_THRSHLD) && + (connList[index].rssiAvg >= RSSI_1M_THRSHLD) && + (connList[index].currPhy != HCI_PHY_1_MBPS) && + (connList[index].currPhy != SP_PHY_NONE)) + { + // try to go to legacy regular data rate + phyRqS = phyRq = HCI_PHY_1_MBPS; + } + else if((connList[index].rssiAvg >= RSSI_S2_THRSHLD) && + (connList[index].rssiAvg < RSSI_1M_THRSHLD) && + (connList[index].currPhy != SP_PHY_NONE)) + { + // try to go to lower data rate S=2(500kb/s) + phyRqS = HCI_PHY_CODED; + phyOpt = LL_PHY_OPT_S2; + phyRq = BLE5_CODED_S2_PHY; + } + else if(connList[index].rssiAvg < RSSI_S2_THRSHLD ) + { + // try to go to lowest data rate S=8(125kb/s) + phyRqS = HCI_PHY_CODED; + phyOpt = LL_PHY_OPT_S8; + phyRq = BLE5_CODED_S8_PHY; + } + if((phyRq != SP_PHY_NONE) && + // First check if the request for this phy change is already not honored then don't request for change + (((connList[index].rqPhy == phyRq) && + (connList[index].phyRqFailCnt < 2)) || + (connList[index].rqPhy != phyRq))) + { + //Initiate PHY change based on RSSI + SimplePeripheral_setPhy(connList[index].connHandle, 0, + phyRqS, phyRqS, phyOpt); + connList[index].phyCngRq = TRUE; + + // If it a request for different phy than failed request, reset the count + if(connList[index].rqPhy != phyRq) + { + // then reset the request phy counter and requested phy + connList[index].phyRqFailCnt = 0; + } + + if(phyOpt == LL_PHY_OPT_NONE) + { + connList[index].rqPhy = phyRq; + } + else if(phyOpt == LL_PHY_OPT_S2) + { + connList[index].rqPhy = BLE5_CODED_S2_PHY; + } + else + { + connList[index].rqPhy = BLE5_CODED_S8_PHY; + } + + } // end of if ((phyRq != SP_PHY_NONE) && ... + } // end of if (connList[index].phyCngRq == FALSE) + } // end of if (rssi != LL_RSSI_NOT_AVAILABLE) + + Display_printf(dispHandle, SP_ROW_RSSI, 0, + "RSSI:%d dBm, AVG RSSI:%d dBm", + (uint32_t)(rssi), + connList[index].rssiAvg); + + } // end of if (status == SUCCESS) + break; + } + + case HCI_LE_READ_PHY: + { + if (status == SUCCESS) + { + Display_printf(dispHandle, SP_ROW_RSSI + 2, 0, "RXPh: %d, TXPh: %d", + pMsg->pReturnParam[3], pMsg->pReturnParam[4]); + } + break; + } + + default: + break; + } // end of switch (pMsg->cmdOpcode) +} + +/********************************************************************* +* @fn SimplePeripheral_initPHYRSSIArray +* +* @brief Initializes the array of structure/s to store data related +* RSSI based auto PHy change +* +* @param connHandle - the connection handle +* +* @param addr - pointer to device address +* +* @return index of connection handle +*/ +static void SimplePeripheral_initPHYRSSIArray(void) +{ + //Initialize array to store connection handle and RSSI values + memset(connList, 0, sizeof(connList)); + for (uint8_t index = 0; index < MAX_NUM_BLE_CONNS; index++) + { + connList[index].connHandle = SP_INVALID_HANDLE; + } +} +/********************************************************************* + // Set default PHY to 1M + * @fn SimplePeripheral_startAutoPhyChange + * + * @brief Start periodic RSSI reads on a link. + * + * @param connHandle - connection handle of link + * @param devAddr - device address + * + * @return SUCCESS: Terminate started + * bleIncorrectMode: No link + * bleNoResources: No resources + */ +static status_t SimplePeripheral_startAutoPhyChange(uint16_t connHandle) +{ + status_t status = FAILURE; + + // Get connection index from handle + uint8_t connIndex = SimplePeripheral_getConnIndex(connHandle); + //Wei + SIMPLEPERIPHERAL_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + // Start Connection Event notice for RSSI calculation + status = Gap_RegisterConnEventCb(SimplePeripheral_connEvtCB, GAP_CB_REGISTER, GAP_CB_CONN_EVENT_ALL, connHandle); + + // Flag in connection info if successful + if (status == SUCCESS) + { + connList[connIndex].isAutoPHYEnable = TRUE; + } + + return status; +} + +/********************************************************************* + * @fn SimplePeripheral_stopAutoPhyChange + * + * @brief Cancel periodic RSSI reads on a link. + * + * @param connHandle - connection handle of link + * + * @return SUCCESS: Operation successful + * bleIncorrectMode: No link + */ +static status_t SimplePeripheral_stopAutoPhyChange(uint16_t connHandle) +{ + // Get connection index from handle + uint8_t connIndex = SimplePeripheral_getConnIndex(connHandle); + //Wei + SIMPLEPERIPHERAL_ASSERT(connIndex < MAX_NUM_BLE_CONNS); + + // Stop connection event notice + Gap_RegisterConnEventCb(NULL, GAP_CB_UNREGISTER, GAP_CB_CONN_EVENT_ALL, connHandle); + + // Also update the phychange request status for active RSSI tracking connection + connList[connIndex].phyCngRq = FALSE; + connList[connIndex].isAutoPHYEnable = FALSE; + + return SUCCESS; +} + +/********************************************************************* + * @fn SimplePeripheral_setPhy + * + * @brief Call the HCI set phy API and and add the handle to a + * list to match it to an incoming command status event + */ +static status_t SimplePeripheral_setPhy(uint16_t connHandle, uint8_t allPhys, + uint8_t txPhy, uint8_t rxPhy, + uint16_t phyOpts) +{ + // Allocate list entry to store handle for command status + spConnHandleEntry_t *connHandleEntry = ICall_malloc(sizeof(spConnHandleEntry_t)); + + if (connHandleEntry) + { + connHandleEntry->connHandle = connHandle; + + // Add entry to the phy command status list + List_put(&setPhyCommStatList, (List_Elem *)connHandleEntry); + + // Send PHY Update + HCI_LE_SetPhyCmd(connHandle, allPhys, txPhy, rxPhy, phyOpts); + } + + return SUCCESS; +} + +/********************************************************************* +* @fn SimplePeripheral_updatePHYStat +* +* @brief Update the auto phy update state machine +* +* @param connHandle - the connection handle +* +* @return None +*/ +static void SimplePeripheral_updatePHYStat(uint16_t eventCode, uint8_t *pMsg) +{ + uint8_t connIndex; + + switch (eventCode) + { + case HCI_LE_SET_PHY: + { + // Get connection handle from list + spConnHandleEntry_t *connHandleEntry = + (spConnHandleEntry_t *)List_get(&setPhyCommStatList); + + if (connHandleEntry) + { + // Get index from connection handle + connIndex = SimplePeripheral_getConnIndex(connHandleEntry->connHandle); + + ICall_free(connHandleEntry); + + // Is this connection still valid? + if (connIndex < MAX_NUM_BLE_CONNS) + { + hciEvt_CommandStatus_t *pMyMsg = (hciEvt_CommandStatus_t *)pMsg; + + if (pMyMsg->cmdStatus == HCI_ERROR_CODE_UNSUPPORTED_REMOTE_FEATURE) + { + // Update the phychange request status for active RSSI tracking connection + connList[connIndex].phyCngRq = FALSE; + connList[connIndex].phyRqFailCnt++; + } + } + } + break; + } + + // LE Event - a Phy update has completed or failed + case HCI_BLE_PHY_UPDATE_COMPLETE_EVENT: + { + hciEvt_BLEPhyUpdateComplete_t *pPUC = + (hciEvt_BLEPhyUpdateComplete_t*) pMsg; + + if(pPUC) + { + // Get index from connection handle + connIndex = SimplePeripheral_getConnIndex(pPUC->connHandle); + + // Is this connection still valid? + if (connIndex < MAX_NUM_BLE_CONNS) + { + // Update the phychange request status for active RSSI tracking connection + connList[connIndex].phyCngRq = FALSE; + + if (pPUC->status == SUCCESS) + { + connList[connIndex].currPhy = pPUC->rxPhy; + } + if(pPUC->rxPhy != connList[connIndex].rqPhy) + { + connList[connIndex].phyRqFailCnt++; + } + else + { + // Reset the request phy counter and requested phy + connList[connIndex].phyRqFailCnt = 0; + connList[connIndex].rqPhy = 0; + } + } + } + + break; + } + + default: + break; + } // end of switch (eventCode) +} + +/********************************************************************* + * @fn SimplePeripheral_menuSwitchCb + * + * @brief Detect menu context switching + * + * @param pMenuObjCurr - the current menu object + * @param pMenuObjNext - the menu object the context is about to switch to + * + * @return none + */ +static void SimplePeripheral_menuSwitchCb(tbmMenuObj_t* pMenuObjCurr, + tbmMenuObj_t* pMenuObjNext) +{ + uint8_t NUMB_ACTIVE_CONNS = linkDB_NumActive(); + + // interested in only the events of + // entering scMenuConnect, spMenuSelectConn, and scMenuMain for now + if (pMenuObjNext == &spMenuSelectConn) + { + static uint8_t* pAddrs; + uint8_t* pAddrTemp; + + if (pAddrs != NULL) + { + ICall_free(pAddrs); + } + + // Allocate buffer to display addresses + pAddrs = ICall_malloc(NUMB_ACTIVE_CONNS * SP_ADDR_STR_SIZE); + + if (pAddrs == NULL) + { + TBM_SET_NUM_ITEM(&spMenuSelectConn, 0); + } + else + { + uint8_t i; + + TBM_SET_NUM_ITEM(&spMenuSelectConn, MAX_NUM_BLE_CONNS); + + pAddrTemp = pAddrs; + + // Add active connection info to the menu object + for (i = 0; i < MAX_NUM_BLE_CONNS; i++) + { + if (connList[i].connHandle != LINKDB_CONNHANDLE_INVALID) + { + // Get the address from the connection handle + linkDBInfo_t linkInfo; + linkDB_GetInfo(connList[i].connHandle, &linkInfo); + // This connection is active. Set the corresponding menu item with + // the address of this connection and enable the item. + memcpy(pAddrTemp, Util_convertBdAddr2Str(linkInfo.addr), + SP_ADDR_STR_SIZE); + TBM_SET_ACTION_DESC(&spMenuSelectConn, i, pAddrTemp); + tbm_setItemStatus(&spMenuSelectConn, (1 << i), SP_ITEM_NONE); + pAddrTemp += SP_ADDR_STR_SIZE; + } + else + { + // This connection is not active. Disable the corresponding menu item. + tbm_setItemStatus(&spMenuSelectConn, SP_ITEM_NONE, (1 << i)); + } + } + } + } + else if (pMenuObjNext == &spMenuMain) + { + // Now we are not in a specific connection's context + + // Clear connection-related message + Display_clearLine(dispHandle, SP_ROW_CONNECTION); + } +} +/********************************************************************* +*********************************************************************/ + +static void bleStack_init(void) +{ + bleStack_buildMenu(); + + //Register the current thread as an ICall dispatcher application + ICall_registerApp(&selfEntity, &syncEvent); + +#ifdef USE_RCOSC + // Set device's Sleep Clock Accuracy +#if ( HOST_CONFIG & ( CENTRAL_CFG | PERIPHERAL_CFG ) ) + HCI_EXT_SetSCACmd(500); +#endif // (CENTRAL_CFG | PERIPHERAL_CFG) + RCOSC_enableCalibration(); +#endif // USE_RCOSC + + // Create an RTOS queue for message from profile to be sent to app. + //Wei + //appMsgQueueHandle = Util_constructQueue(&appMsgQueue); + Util_constructQueue(&g_POSIX_appMsgQueue); + + // Create one-shot clock for internal periodic events. + //Wei + Util_constructClock(&clkPeriodic, (void *)SimplePeripheral_clockHandler, + SP_PERIODIC_EVT_PERIOD, 0, false, (uint32_t)&argPeriodic); + + // Set the Device Name characteristic in the GAP GATT Service + // For more information, see the section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName); + + // Configure GAP + { + uint16_t paramUpdateDecision = DEFAULT_PARAM_UPDATE_REQ_DECISION; + + // Pass all parameter update requests to the app for it to decide + GAP_SetParamValue(GAP_PARAM_LINK_UPDATE_DECISION, paramUpdateDecision); + } + + // Setup the GAP Bond Manager. For more information see the GAP Bond Manager + // section in the User's Guide + setBondManagerParameters(); + // Initialize GATT attributes + GGS_AddService(GAP_SERVICE); // GAP GATT Service + GATTServApp_AddService(GATT_ALL_SERVICES); // GATT Service + DevInfo_AddService(); // Device Information Service + SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile + + // Setup the SimpleProfile Characteristic Values + // For more information, see the GATT and GATTServApp sections in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + { + uint8_t charValue1 = 1; + uint8_t charValue2 = 2; + uint8_t charValue3 = 3; + uint8_t charValue4 = 4; + uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = { 1, 2, 3, 4, 5 }; + + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, sizeof(uint8_t), + &charValue1); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, sizeof(uint8_t), + &charValue2); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, sizeof(uint8_t), + &charValue3); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, sizeof(uint8_t), + &charValue4); + SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, + charValue5); + } + + // Register callback with SimpleGATTprofile + SimpleProfile_RegisterAppCBs(&SimplePeripheral_simpleProfileCBs); + + // Start Bond Manager and register callback + VOID GAPBondMgr_Register(&SimplePeripheral_BondMgrCBs); + + // Register with GAP for HCI/Host messages. This is needed to receive HCI + // events. For more information, see the HCI section in the User's Guide: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + GAP_RegisterForMsgs(selfEntity); + + // Register for GATT local events and ATT Responses pending for transmission + GATT_RegisterForMsgs(selfEntity); + + // Set default values for Data Length Extension + // Extended Data Length Feature is already enabled by default + { + // Set initial values to maximum, RX is set to max. by default(251 octets, 2120us) + // Some brand smartphone is essentially needing 251/2120, so we set them here. + #define APP_SUGGESTED_PDU_SIZE 251 //default is 27 octets(TX) + #define APP_SUGGESTED_TX_TIME 2120 //default is 328us(TX) + + // This API is documented in hci.h + // See the LE Data Length Extension section in the BLE5-Stack User's Guide for information on using this command: + // http://software-dl.ti.com/lprf/ble5stack-latest/ + HCI_LE_WriteSuggestedDefaultDataLenCmd(APP_SUGGESTED_PDU_SIZE, APP_SUGGESTED_TX_TIME); + } + + // Initialize GATT Client + GATT_InitClient(""); + + // Init key debouncer + Board_initKeys(SimplePeripheral_keyChangeHandler); + + // Initialize Connection List + SimplePeripheral_clearConnListEntry(LINKDB_CONNHANDLE_ALL); + + BLE_LOG_INT_TIME(0, BLE_LOG_MODULE_APP, "APP : ---- call GAP_DeviceInit", GAP_PROFILE_PERIPHERAL); + //Initialize GAP layer for Peripheral role and register to receive GAP events + GAP_DeviceInit(GAP_PROFILE_PERIPHERAL, selfEntity, addrMode, &pRandomAddress); + + // Initialize array to store connection handle and RSSI values + SimplePeripheral_initPHYRSSIArray(); + + // The type of display is configured based on the BOARD_DISPLAY_USE... + // preprocessor definitions + dispHandle = Display_open(Display_Type_ANY, NULL); + + // Initialize Two-Button Menu module + TBM_SET_TITLE(&spMenuMain, "Simple Peripheral"); + tbm_setItemStatus(&spMenuMain, TBM_ITEM_NONE, TBM_ITEM_ALL); + + tbm_initTwoBtnMenu(dispHandle, &spMenuMain, 5, SimplePeripheral_menuSwitchCb); + Display_printf(dispHandle, SP_ROW_SEPARATOR_1, 0, "===================="); + +#ifdef PTM_MODE + // Intercept NPI RX events. + NPITask_registerIncomingRXEventAppCB(simple_peripheral_handleNPIRxInterceptEvent, INTERCEPT); + + // Register for Command Status information + HCI_TL_Init(NULL, (HCI_TL_CommandStatusCB_t) simple_peripheral_sendToNPI, NULL, selfEntity); + + // Register for Events + HCI_TL_getCmdResponderID(ICall_getLocalMsgEntityId(ICALL_SERVICE_CLASS_BLE_MSG, selfEntity)); + + // Inform Stack to Initialize PTM + HCI_EXT_EnablePTMCmd(); +#endif // PTM_MODE +} + +/********************************************************************* + * PUBLIC FUNCTIONS + */ + +/********************************************************************* + * @fn simple_peripheral_spin + * + * @brief Spin forever + * + * @param none + */ +static void simple_peripheral_spin(void) +{ + volatile uint8_t x = 0; + + while(1) + { + x++; + } +} + +#ifdef PTM_MODE +/********************************************************************* +* @fn simple_peripheral_handleNPIRxInterceptEvent +* +* @brief Intercept an NPI RX serial message and queue for this application. +* +* @param pMsg - a NPIMSG_msg_t containing the intercepted message. +* +* @return none. +*/ +void simple_peripheral_handleNPIRxInterceptEvent(uint8_t *pMsg) +{ + // Send Command via HCI TL + HCI_TL_SendToStack(((NPIMSG_msg_t *)pMsg)->pBuf); + + // The data is stored as a message, free this first. + ICall_freeMsg(((NPIMSG_msg_t *)pMsg)->pBuf); + + // Free container. + ICall_free(pMsg); +} + +/********************************************************************* +* @fn simple_peripheral_sendToNPI +* +* @brief Create an NPI packet and send to NPI to transmit. +* +* @param buf - pointer HCI event or data. +* +* @param len - length of buf in bytes. +* +* @return none +*/ +static void simple_peripheral_sendToNPI(uint8_t *buf, uint16_t len) +{ + npiPkt_t *pNpiPkt = (npiPkt_t *)ICall_allocMsg(sizeof(npiPkt_t) + len); + + if (pNpiPkt) + { + pNpiPkt->hdr.event = buf[0]; //Has the event status code in first byte of payload + pNpiPkt->hdr.status = 0xFF; + pNpiPkt->pktLen = len; + pNpiPkt->pData = (uint8 *)(pNpiPkt + 1); + + memcpy(pNpiPkt->pData, buf, len); + + // Send to NPI + // Note: there is no need to free this packet. NPI will do that itself. + NPITask_sendToHost((uint8_t *)pNpiPkt); + } +} +#endif // PTM_MODE + +//self define AssertHandler +void AssertHandler(uint8 assertCause, uint8 assertSubcause) +{ + //do nothing for now, need to define at application layer + switch (assertCause) + { + case HAL_ASSERT_CAUSE_OUT_OF_MEMORY: + otPlatLog(OT_LOG_LEVEL_DEBG, OT_LOG_REGION_PLATFORM, "OUT_OF_MEMORY\n"); + break; + + case HAL_ASSERT_CAUSE_INTERNAL_ERROR: + // check the subcause + if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR) + { + otPlatLog(OT_LOG_LEVEL_DEBG, OT_LOG_REGION_PLATFORM, "FW INTERNAL ERROR\n"); + } + else + { + otPlatLog(OT_LOG_LEVEL_DEBG, OT_LOG_REGION_PLATFORM, "INTERNAL ERROR\n"); + } + break; + + case HAL_ASSERT_CAUSE_ICALL_ABORT: + HAL_ASSERT_SPINLOCK; + break; + + case HAL_ASSERT_CAUSE_ICALL_TIMEOUT: + HAL_ASSERT_SPINLOCK; + break; + + case HAL_ASSERT_CAUSE_WRONG_API_CALL: + HAL_ASSERT_SPINLOCK; + break; + + default: + HAL_ASSERT_SPINLOCK; + } + +} + diff --git a/examples/apps/cli/bleAppTask.h b/examples/apps/cli/bleAppTask.h new file mode 100644 index 0000000..592db0b --- /dev/null +++ b/examples/apps/cli/bleAppTask.h @@ -0,0 +1,5 @@ +void bleAppTask_init(); +static void BleMain(void *); +static void bleStack_init(); +#define BLEAPP_TASK_STACK_SIZE (2048) +#define BLEAPP_TASK_PRIORITY 4 diff --git a/examples/apps/cli/bleStackApp.h b/examples/apps/cli/bleStackApp.h new file mode 100644 index 0000000..e14c78a --- /dev/null +++ b/examples/apps/cli/bleStackApp.h @@ -0,0 +1,103 @@ + +/****************************************************************************** + + @file simple_peripheral.h + + @brief This file contains the Simple Peripheral sample application + definitions and prototypes. + + Group: WCS, BTS + Target Device: cc13xx_cc26xx + + ****************************************************************************** + + Copyright (c) 2013-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + + + *****************************************************************************/ + +#ifndef SIMPLEPERIPHERAL_H +#define SIMPLEPERIPHERAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************* + * INCLUDES + */ +#include + +/********************************************************************* +* EXTERNAL VARIABLES +*/ + +/********************************************************************* + * CONSTANTS + */ + +/********************************************************************* + * MACROS + */ + +/********************************************************************* + * FUNCTIONS + */ + +/* + * Task creation function for the Simple Peripheral. + */ +extern void SimplePeripheral_createTask(void); + +/* + * Functions for menu action + */ +/* Actions for Menu: Choose connection to work with */ +bool SimplePeripheral_doSelectConn(uint8 index); + +/* Action for Menu: AutoConnect */ +bool SimplePeripheral_doAutoConnect(uint8_t index); + +/* Actions for Menu: Set PHY - Select */ +bool SimplePeripheral_doSetConnPhy(uint8 index); + +/********************************************************************* +*********************************************************************/ + +#ifdef __cplusplus +} +#endif + +#endif /* SIMPLEPERIPHERAL_H */ + diff --git a/examples/apps/cli/bleStackMenu.c b/examples/apps/cli/bleStackMenu.c new file mode 100644 index 0000000..30a4005 --- /dev/null +++ b/examples/apps/cli/bleStackMenu.c @@ -0,0 +1,61 @@ +#include +#include + +#include +#include "bleStack_menu.h" +#include "bleStackApp.h" +#include "ti_ble_config.h" + +/* Main Menu Object */ +tbmMenuObj_t spMenuMain; +tbmMenuObj_t spMenuAutoConnect; +tbmMenuObj_t spMenuSelectConn; +tbmMenuObj_t spMenuPerConn; +tbmMenuObj_t spMenuConnPhy; + +/* + * Menu Lists Initializations + */ + +void bleStack_buildMenu(void) +{ +// Menu: Main +// upper: none + MENU_OBJ(spMenuMain, NULL, 2, NULL) + MENU_ITEM_SUBMENU(spMenuMain,0,&spMenuSelectConn) + MENU_ITEM_SUBMENU(spMenuMain,1,&spMenuAutoConnect) + MENU_OBJ_END + +// Menu: SelectDev +// upper: Main +// NOTE: The number of items in this menu object shall be +// equal to or greater than MAX_NUM_BLE_CONNS + MENU_OBJ(spMenuSelectConn, "Work with", MAX_NUM_BLE_CONNS, &spMenuMain) + MENU_ITEM_MULTIPLE_ACTIONS(spMenuSelectConn, MAX_NUM_BLE_CONNS, NULL, SimplePeripheral_doSelectConn) + MENU_OBJ_END + +// Menu: AutoConnect +// upper: Main + MENU_OBJ(spMenuAutoConnect, "Set AutoConnect", 3, &spMenuMain) + MENU_ITEM_ACTION(spMenuAutoConnect,0,"Disable", SimplePeripheral_doAutoConnect) + MENU_ITEM_ACTION(spMenuAutoConnect,1,"Group A", SimplePeripheral_doAutoConnect) + MENU_ITEM_ACTION(spMenuAutoConnect,2,"Group B", SimplePeripheral_doAutoConnect) + MENU_OBJ_END + +// Menu: PerConnection +// upper: SelectDevice + MENU_OBJ(spMenuPerConn, NULL, 1, &spMenuSelectConn) + MENU_ITEM_SUBMENU(spMenuPerConn,0,&spMenuConnPhy) + MENU_OBJ_END + +// Menu: ConnPhy +// upper: Select Device + MENU_OBJ(spMenuConnPhy, "Set Conn PHY Preference", 6, &spMenuPerConn) + MENU_ITEM_ACTION(spMenuConnPhy,0,"1 Mbps", SimplePeripheral_doSetConnPhy) + MENU_ITEM_ACTION(spMenuConnPhy,1,"2 Mbps", SimplePeripheral_doSetConnPhy) + MENU_ITEM_ACTION(spMenuConnPhy,2,"1 & 2 Mbps", SimplePeripheral_doSetConnPhy) + MENU_ITEM_ACTION(spMenuConnPhy,3,"Coded", SimplePeripheral_doSetConnPhy) + MENU_ITEM_ACTION(spMenuConnPhy,4,"1 & 2 Mbps, & Coded", SimplePeripheral_doSetConnPhy) + MENU_ITEM_ACTION(spMenuConnPhy,5,"Auto PHY change", SimplePeripheral_doSetConnPhy) + MENU_OBJ_END +} diff --git a/examples/apps/cli/bleStack_menu.h b/examples/apps/cli/bleStack_menu.h new file mode 100644 index 0000000..51a2b4f --- /dev/null +++ b/examples/apps/cli/bleStack_menu.h @@ -0,0 +1,91 @@ +/****************************************************************************** + + @file simple_peripheral_menu.h + + @brief This file contains menu objects for simple_peripheral. + + Group: WCS BTS + Target Device: cc13xx_cc26xx + + ****************************************************************************** + + Copyright (c) 2016-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + + + *****************************************************************************/ + +#ifndef SIMPLE_PERIPHERAL_MENU_H +#define SIMPLE_PERIPHERAL_MENU_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +// Menu item indices. +#define SP_ITEM_NONE TBM_ITEM_NONE +#define SP_ITEM_ALL TBM_ITEM_ALL + +// Note: The defines should be updated accordingly if there is any change +// in the order of the items of the menu objects the items belong to. +#define SP_ITEM_SELECT_CONN TBM_ITEM(0) // "Work with" +#define SP_ITEM_AUTOCONNECT TBM_ITEM(1) // "Auto Connect" + +/* + * Menus Declarations + */ + +/* Main Menu Object */ +extern tbmMenuObj_t spMenuMain; + +/* Items of (Main) */ +/* Action items are defined in simple_peripheral_menu.c */ + +/* + * Menus Declarations + */ + +/* Main Menu Object */ +extern tbmMenuObj_t spMenuMain; +extern tbmMenuObj_t spMenuAutoConnect; +extern tbmMenuObj_t spMenuSelectConn; +extern tbmMenuObj_t spMenuPerConn; +extern tbmMenuObj_t spMenuConnPhy; + +void bleStack_buildMenu(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SIMPLE_PERIPHERAL_MENU_H */ \ No newline at end of file diff --git a/examples/apps/cli/freertos_main.c b/examples/apps/cli/freertos_main.c index 4aae8eb..df7c0f1 100644 --- a/examples/apps/cli/freertos_main.c +++ b/examples/apps/cli/freertos_main.c @@ -43,6 +43,17 @@ #include #include +#include +#include "bcomdef.h" +#include + +#ifndef USE_DEFAULT_USER_CFG +#include "ble_user_config.h" +#include "ble_stack_api.h" +// BLE user defined configuration +icall_userCfg_t user0Cfg = BLE_USER_CFG; +#endif // USE_DEFAULT_USER_CFG + // The entry point for the application extern int app_main(int argc, char *argv[]); #define APP_STACK_SIZE (2048) @@ -50,6 +61,18 @@ extern int app_main(int argc, char *argv[]); StackType_t appStack[APP_STACK_SIZE]; StaticTask_t appTaskBuffer; +#define BLEAPP_TASK_STACK_SIZE (2048) +static TaskHandle_t BLEAPPTaskHandle; +#define BLEAPP_TASK_PRIORITY 4 + +#include +#define TOTAL_ICALL_HEAP_SIZE (0xf700) + +extern void appMain(void); + +__attribute__((section(".heap"))) uint8_t ucHeap[TOTAL_ICALL_HEAP_SIZE]; +uint32_t heapSize = TOTAL_ICALL_HEAP_SIZE; + void vApplicationStackOverflowHook(void) { while (1) @@ -64,9 +87,16 @@ void vTaskCode(void *pvParameters) app_main(0, NULL); } +void AssertHandler(uint8_t assertCause, uint8_t assertSubcause) +{ +} + int main(void) { + halAssertCback = AssertHandler; + RegisterAssertCback(AssertHandler); Board_init(); + bpool((void *) ucHeap, TOTAL_ICALL_HEAP_SIZE); GPIO_init(); @@ -80,6 +110,17 @@ int main(void) SHA2_init(); + user0Cfg.appServiceInfo->timerTickPeriod = ICall_getTickPeriod(); + user0Cfg.appServiceInfo->timerMaxMillisecond = ICall_getMaxMSecs(); + +#if 0 + /* Initialize ICall module */ + ICall_init(); + + /* Start tasks of external images */ + ICall_createRemoteTasks(); +#endif + if (NULL == xTaskCreateStatic(vTaskCode, "APP", APP_STACK_SIZE, NULL, tskIDLE_PRIORITY + 2, appStack, &appTaskBuffer)) { @@ -87,6 +128,8 @@ int main(void) ; } + //bleAppTask_init(); + appMain(); vTaskStartScheduler(); // Should never get here. diff --git a/examples/apps/cli/main.c b/examples/apps/cli/main.c index e1fc63c..8b5d332 100644 --- a/examples/apps/cli/main.c +++ b/examples/apps/cli/main.c @@ -41,6 +41,8 @@ #include "lib/platform/reset_util.h" +otInstance *instance; + /** * This function initializes the CLI app. * @@ -96,7 +98,7 @@ static const otCliCommand kCommands[] = { int app_main(int argc, char *argv[]) { - otInstance *instance; + OT_SETUP_RESET_JUMP(argv); @@ -156,3 +158,27 @@ void otPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char *aFormat va_end(ap); } #endif + +otInstance *OtInstance_get(void) +{ + otInstance *ret; + + if (NULL != instance) + { + ret = instance; + } + else + { + /* lock and unlock the API to make sure that the stack is initialized + * before the caller tries to use this pointer. + */ + // FIXME: Not sure about the locking here, as these symbols are + // not defined. + // + //OtRtosApi_lock(); + ret = instance; + //OtRtosApi_unlock(); + } + + return ret; +} \ No newline at end of file diff --git a/examples/apps/cli/osal_icall_ble.c b/examples/apps/cli/osal_icall_ble.c new file mode 100755 index 0000000..ac15a0a --- /dev/null +++ b/examples/apps/cli/osal_icall_ble.c @@ -0,0 +1,291 @@ +/****************************************************************************** + + @file osal_icall_ble.c + + @brief This file contains function that allows user setup tasks + + Group: WCS, BTS + Target Device: cc13xx_cc26xx + + ****************************************************************************** + + Copyright (c) 2013-2023, Texas Instruments Incorporated + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of Texas Instruments Incorporated nor the names of + its contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + ****************************************************************************** + + + *****************************************************************************/ + +/************************************************************************************************** + * INCLUDES + **************************************************************************************************/ +#include +#include "hal_types.h" +#include "hal_mcu.h" +#include "osal.h" +#include "osal_tasks.h" +#include "osal_snv.h" + + +/* LL */ +#include "ll.h" + +#if defined ( OSAL_CBTIMER_NUM_TASKS ) + #include "osal_cbtimer.h" +#endif + +/* L2CAP */ +#include "l2cap.h" + +/* gap */ +#include "gap.h" + +#if defined ( GAP_BOND_MGR ) + #include "gapbondmgr_internal.h" +#endif + +/* GATT */ +#include "gatt.h" + +/* Application */ +#include "hci_tl.h" + +#include "gattservapp.h" + +#include "gapbondmgr.h" + +#include "ble_user_config.h" +#include "ble_dispatch.h" +#include "ti_ble_config.h" + + +#ifdef USE_ICALL +#ifdef CC23X0 +#include "icall.h" +#else +#include "icall_jt.h" +#endif + +#ifdef ICALL_LITE +#include "icall_lite_translation.h" +#include "ble_dispatch_lite.h" +#endif /* ICALL_LITE */ + +#endif /* USE_ICALL */ + +/********************************************************************* + * GLOBAL VARIABLES + */ + +// The order in this table must be identical to the task initialization calls below in osalInitTask. +const pTaskEventHandlerFn tasksArr[] = +{ + LL_ProcessEvent, // task 0 + HCI_ProcessEvent, // task 1 +#if defined ( OSAL_CBTIMER_NUM_TASKS ) + OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ), // task 2 +#endif + L2CAP_ProcessEvent, // task 3 + GAP_ProcessEvent, // task 4 + SM_ProcessEvent, // task 5 + GATT_ProcessEvent, // task 6 + GATTServApp_ProcessEvent, // task 7 +#if defined ( GAP_BOND_MGR ) + GAPBondMgr_ProcessEvent, // task 8 +#endif +#ifdef ICALL_LITE + ble_dispatch_liteProcess, // task 9 +#else + bleDispatch_ProcessEvent // task 9 +#endif /* ICALL_LITE */ +}; + +const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] ); +uint16 *tasksEvents; + +/********************************************************************* + * FUNCTIONS + *********************************************************************/ + +/********************************************************************* + * @fn osalInitTasks + * + * @brief This function invokes the initialization function for each task. + * + * @param void + * + * @return none + */ +void osalInitTasks( void ) +{ + ICall_EntityID entity; + ICall_SyncHandle syncHandle; + uint8 taskID = 0; + uint8 i; + + uint8_t cfg_GATTServApp_att_delayed_req = 0; + uint8_t cfg_gapBond_gatt_no_service_changed = 0; +#if defined ( GAP_BOND_MGR ) + uint8_t cfg_gapBond_gatt_no_client = 0; +#endif + +#if defined ( ATT_DELAYED_REQ ) + cfg_GATTServApp_att_delayed_req = 1; +#endif +#if defined ( GATT_NO_SERVICE_CHANGED ) + cfg_gapBond_gatt_no_service_changed = 1; +#endif +#if defined ( GATT_NO_CLIENT ) + cfg_gapBond_gatt_no_client = 1; +#endif + + tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); + osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); + + /* LL Task */ + LL_Init( taskID++ ); + + /* HCI Task */ + HCI_Init( taskID++ ); + +#if defined ( OSAL_CBTIMER_NUM_TASKS ) + /* Callback Timer Tasks */ + osal_CbTimerInit( taskID ); + taskID += OSAL_CBTIMER_NUM_TASKS; +#endif + + /* L2CAP Task */ + L2CAP_Init( taskID++ ); + + /* GAP Task */ + GAP_Init( taskID++ ); + + /* SM Task */ + SM_Init( taskID++ ); + + /* GATT Task */ + GATT_Init( taskID++ ); + + /* GATT Server App Task */ + GATTServApp_Init( taskID++, cfg_GATTServApp_att_delayed_req, cfg_gapBond_gatt_no_service_changed ); + +#if defined ( GAP_BOND_MGR ) + /* Bond Manager Task */ + GAPBondMgr_Init( taskID++, GAP_BONDINGS_MAX, GAP_CHAR_CFG_MAX, cfg_gapBond_gatt_no_client, cfg_gapBond_gatt_no_service_changed); +#endif + +#ifdef ICALL_LITE + ble_dispatch_liteInit(taskID++); +#else + /* ICall BLE Dispatcher Task */ + bleDispatch_Init( taskID ); +#endif /* ICALL_LITE */ + +#if defined ( NOTIFY_PARAM_UPDATE_RJCT ) + HCI_ParamUpdateRjctEvtRegister(); +#endif + + // ICall enrollment + /* Enroll the service that this stack represents */ + ICall_enrollService(ICALL_SERVICE_CLASS_BLE, NULL, &entity, &syncHandle); + +#ifndef ICALL_LITE + /* Enroll the obtained dispatcher entity and OSAL task ID of HCI Ext App + * to OSAL so that OSAL can route the dispatcher message into + * the appropriate OSAL task. + */ + osal_enroll_dispatchid(taskID, entity); +#endif /* ICALL_LITE */ + /* Register all other OSAL tasks to use the registered dispatcher entity + * ID as the source of dispatcher messages, even though the other OSAL + * tasks didn't register themselves to receive messages from application. + */ + for (i = 0; i < taskID; i++) + { + osal_enroll_senderid(i, entity); + } +} + +/** + * Main entry function for the stack image + */ +int stack_main( void *arg ) +{ + /* User reconfiguration of BLE Controller and Host variables */ +#ifdef ICALL_JT + setBleUserConfig( (icall_userCfg_t *)arg ); +#else /* !(ICALL_JT) */ + setBleUserConfig( (bleUserCfg_t *)arg ); +#endif /* ICALL_JT */ + + /* Establish OSAL for a stack service that requires accompanying + * messaging service */ + if (ICall_enrollService(ICALL_SERVICE_CLASS_BLE_MSG, + (ICall_ServiceFunc) osal_service_entry, + &osal_entity, + &osal_syncHandle) != ICALL_ERRNO_SUCCESS) + { + /* abort */ + ICall_abort(); + } + + // Disable interrupts + halIntState_t state; + HAL_ENTER_CRITICAL_SECTION(state); + +#if defined(ICALL_LITE) && (!defined(STACK_LIBRARY)) + { + icall_liteTranslationInit((uint32_t*)bleAPItable); + } +#endif /* ICALL_LITE */ + +#ifdef ICALL_LITE + { + osal_set_icall_hook(icall_liteMsgParser); + } +#endif /* ICALL_LITE */ + + // Initialize NV System + osal_snv_init( ); + + // Initialize the operating system + osal_init_system(); + + // Allow interrupts + HAL_EXIT_CRITICAL_SECTION(state); + + osal_start_system(); // No Return from here + + return 0; // Shouldn't get here. +} + +/********************************************************************* +*********************************************************************/ diff --git a/script/build b/script/build index 303e9b9..1b96ad8 100755 --- a/script/build +++ b/script/build @@ -83,7 +83,7 @@ build() TICLANG_ARMCOMPILER=${TICLANG_ARMCOMPILER} \ GENERATOR=Ninja - ${CMAKE} -GNinja -DOT_COMPILE_WARNING_AS_ERROR=ON "$@" "${OT_SRCDIR}" -B ${builddir} + ${CMAKE} -GNinja -DCMAKE_VERBOSE_MAKEFILE=ON -DOT_COMPILE_WARNING_AS_ERROR=ON "$@" "${OT_SRCDIR}" -B ${builddir} if [[ -n ${OT_CMAKE_NINJA_TARGET[*]} ]]; then ${CMAKE} --build ${builddir} "${OT_CMAKE_NINJA_TARGET[@]}" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e28415c..85668d2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,24 +48,144 @@ if(TI_SIMPLELINK_KERNEL STREQUAL "freertos") ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_radio_config.c ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_radio_config.h + # JJM - adding the BLE configuration source + ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_ble_config.c + ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_ble_config.h + + # TI SimpleLink FreeRTOS configuration and build is not possible until # configTICK_RATE_HZ is configurable and source directory set correctly. #${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_freertos_config.c #${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_freertos_portable_config.c #${CMAKE_CURRENT_BINARY_DIR}/syscfg/FreeRTOSConfig.h ) + + # JJM - System Cofiguration Include Paths + set(SYSCONFIG_INCLUDES + #DMM + ${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm/thread/platform + ${TI_SIMPLELINK_SDK_DIR}/source/ti + ${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm + ${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm/apps + ${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm/apps/common/thread + ${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm/apps/common/thread/source/activity + ${TI_SIMPLELINK_SDK_DIR}/source/ti/common/nv + + # + # JJM - Note: the include paths below are a mirror (or an attempt to mirror) + # the /Includes folder from the CCS simple-peripheral project + # + + # BLE + # JJM - including /src here to avoid duplicates of FreeRTOSConfig.h. I think this is ok? + ${PROJECT_SOURCE_DIR}/src + + # BLE (cont) + ${TI_SIMPLELINK_SDK_DIR}/source/ti/drivers/dpl + ${TI_SIMPLELINK_SDK_DIR}/source + ${TI_SIMPLELINK_SDK_DIR}/source/ti + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/controller/cc26xx/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/rom + ${TI_SIMPLELINK_SDK_DIR}/source/ti/common/cc26xx + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/hal/src/target/_common + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx/npi/stack/ + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/hal/src/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/heapmgr + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/profiles/dev_info + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/profiles/simple_profile + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/src/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/npi/src/ + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/osal/src/inc + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/services/src/saddr + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/services/src/sdata + ${TI_SIMPLELINK_SDK_DIR}/source/ti/common/nv + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/src + ${TI_SIMPLELINK_SDK_DIR}/kernel/tirtos7/packages + ${TI_SIMPLELINK_SDK_DIR}/source/ti/devices/cc13x4_cc26x4 + ${TI_SIMPLELINK_SDK_DIR}/source/ti/posix/gcc + + ${TI_SIMPLELINK_SDK_DIR}/kernel/freertos + ${TI_SIMPLELINK_SDK_DIR}/kernel + + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/common/cc26xx/rcosc + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/npi/src/inc + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack/common/cc26xx/freertos + ) + + # JJM - setup the source files required for DMM builds + set(DMM_OUTPUT_C + ${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm/apps/common/thread/source/activity/dmm_thread_activity.c + ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_dmm_application_policy.c + ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_dmm_application_policy.h + ) + + # JJM - setup the source files for BLE + set(BLE_OUTPUT_C + # basic ble common/BLEAppUtil + ${TI_SIMPLELINK_SDK_DIR}/source/ti/bleapp/ble_app_util/src/bleapputil_init.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/bleapp/ble_app_util/src/bleapputil_process.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/bleapp/ble_app_util/src/bleapputil_stack_callbacks.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/bleapp/ble_app_util/src/bleapputil_task.c + + # basic ble common/iCall + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/src/icall_POSIX.c + + # basic ble common/iCallBLE + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/app/ble_stack_api.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/app/ble_user_config.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/app/icall_api_lite.c + + # basic ble common/Profiles/simple_gatt + ${TI_SIMPLELINK_SDK_DIR}/source/ti/bleapp/profiles/simple_gatt/simple_gatt_profile.c + + # basic ble common/Service/dev_info + ${TI_SIMPLELINK_SDK_DIR}/source/ti/bleapp/services/dev_info/dev_info_service.c + + # basic ble common/Startup + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/stack/ble_user_config_stack.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/bleapp/profiles/simple_gatt/simple_gatt_profile.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/rom/agama_r1/rom_init.c + + # basic ble iCall + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/src/icall_cc2650.c + ${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/src/icall_user_config.c + + # JJM - mirror simple peripheral iCallBLE folder + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/stack/ble_user_config_stack.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/app/ble_user_config.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/app/icall_api_lite.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/icall/app/icall_hci_tl.c + + # JJM - mirror the simple peripheral Profiles folder + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/profiles/dev_info/cc26xx/devinfoservice.c + #${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/profiles/simple_profile/cc26xx/simple_gatt_profile.c + ) + set(SYSCONFIG_OUTPUT_OTHER ${CMAKE_CURRENT_BINARY_DIR}/syscfg/syscfg_c.rov.xs ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_build_config.opt + # JJM - this doesn't seem to work for some reason, had to add to User Defs + ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_ble_app_config.opt ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_utils_build_linker.cmd.genlibs ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_utils_runtime_Makefile ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_utils_runtime_model.gv + + # mirrors the simple-peripheral Startup folder + # JJM - cannot get this to link for stack_main() + #${TI_SIMPLELINK_SDK_DIR}/source/ti/dmm/apps/common/ble_remote_display/stack/osal_icall_ble.c ) set(GENLIBS_INCLUDES -L${TI_SIMPLELINK_SDK_DIR}/source ) elseif(TI_SIMPLELINK_KERNEL STREQUAL "tirtos7") + + # JJM - not used, using FreeRTOS + set(SYSCONFIG_OUTPUT_C ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_drivers_config.h ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_radio_config.h @@ -99,6 +219,8 @@ add_custom_command( OUTPUT ${SYSCONFIG_OUTPUT_C} ${SYSCONFIG_OUTPUT_OTHER} + ${DMM_OUTPUT_C} + ${BLE_OUTPUT_C} COMMAND ${TI_SYSCONFIG_CMD} -s ${TI_SIMPLELINK_SDK_DIR}/.metadata/product.json @@ -114,6 +236,8 @@ add_custom_command( add_library(openthread-cc13xx_cc26xx ${SYSCONFIG_OUTPUT_C} + ${DMM_OUTPUT_C} + ${BLE_OUTPUT_C} alarm.c alarm_micro.c diag.c @@ -131,6 +255,7 @@ add_library(openthread-cc13xx_cc26xx list(APPEND TI_PLATFORM_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}) +# retargeted target_link_libraries(openthread-cc13xx_cc26xx PUBLIC cc13xx-cc26xx-sdk @@ -139,19 +264,69 @@ target_link_libraries(openthread-cc13xx_cc26xx ${GENLIBS_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_utils_build_linker.cmd.genlibs cc13xx-cc26xx-driverlib + -Wl,${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_utils_build_linker.cmd.genlibs PRIVATE ot-config ) +# JJM - setting the user compile definitions here as there seems to be +# an issue with the .opt files +set(USR_COMPILE_DEFINITIONS + "USE_DMM" + "SYSCFG" + "CC13X4" + "CC13XX" + "POWER_SAVING" + "TBM_ACTIVE_ITEMS_ONLY" + "STACK_LIBRARY" + "EXTENDED_STACK_SETTINGS=EXTENDED_STACK_SETTINGS_DEFAULT" + "NPI_USE_UART" + "ICALL_EVENTS" + "ICALL_JT" + "ICALL_LITE" + "ICALL_STACK0_ADDR" + "USE_ICALL" + "ICALL_MAX_NUM_ENTITIES=6" + "ICALL_MAX_NUM_TASKS=3" + "OSAL_CBTIMER_NUM_TASKS=1" + "ONE_BLE_LIB_SIZE_OPTIMIZATION" + + # the following are from ti_build_config.opt + "HOST_CONFIG=PERIPHERAL_CFG" + "USE_AE" + "GAP_BOND_MGR" + "HCI_TL_NONE" + "FREERTOS" + + # from basic_ble_LP_EM_CC1354P10_1_freertos_ticlang + "ICALL_NO_APP_EVENTS" + "UARTLOG_ENABLE" + "uartlog_FILE=0" + "DeviceFamily_CC13X4" + "FLASH_ONLY_BUILD" + "NVOCMP_NWSAMEITEM=1" + "EM_CC1354P10_1_LP" + "NVOCMP_POSIX_MUTEX" +) + +set(APPEND CMAKE_C_FLAGS -std=c99) + target_compile_definitions(openthread-cc13xx_cc26xx PUBLIC ${OT_PLATFORM_DEFINES} OT_TI_KERNEL_${TI_SIMPLELINK_KERNEL} + # JJM - add in the user compile definitions + ${USR_COMPILE_DEFINITIONS} ) target_compile_options(openthread-cc13xx_cc26xx - PRIVATE - ${OT_CFLAGS} + PUBLIC + ${OT_CFLAGS} + @${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_ble_app_config.opt + @${CMAKE_CURRENT_BINARY_DIR}/syscfg/ti_build_config.opt + @${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/config/build_components.opt + @${TI_SIMPLELINK_SDK_DIR}/source/ti/ble5stack_flash/config/factory_config.opt + -O0 ) target_include_directories(openthread-cc13xx_cc26xx diff --git a/src/FreeRTOSConfig.h b/src/FreeRTOSConfig.h index 59cf79d..8b71feb 100644 --- a/src/FreeRTOSConfig.h +++ b/src/FreeRTOSConfig.h @@ -57,7 +57,7 @@ #if defined(DeviceFamily_CC13X2_CC26X2) \ || defined(DeviceFamily_CC13X2) \ || defined(DeviceFamily_CC26X2) -#define configTOTAL_HEAP_SIZE ((size_t)(0x4000)) +#define configTOTAL_HEAP_SIZE ((size_t)(0)) #define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 #elif defined(DeviceFamily_CC13X2X7_CC26X2X7) \ @@ -69,7 +69,8 @@ #elif defined(DeviceFamily_CC13X4_CC26X4) \ || defined(DeviceFamily_CC13X4) \ || defined(DeviceFamily_CC26X4) -#define configTOTAL_HEAP_SIZE ((size_t)(0x14000)) +//#define configTOTAL_HEAP_SIZE ((size_t)(0x14000)) +#define configTOTAL_HEAP_SIZE ((size_t) (0)) #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 /* TrustZone/PSA settings */ /* We do not set ENABLE_TRUSTZONE, as this is only for Secure Side function call support */ @@ -124,6 +125,7 @@ /* Required by TI driver implementations */ #define configSUPPORT_STATIC_ALLOCATION 1 +#define configAPPLICATION_ALLOCATED_HEAP 1 /* Constants that build features in or out. */ #define configUSE_MUTEXES 1 diff --git a/src/openthread.syscfg b/src/openthread.syscfg index 7b93ec3..b03913d 100755 --- a/src/openthread.syscfg +++ b/src/openthread.syscfg @@ -1,229 +1,180 @@ -/* - * Copyright (c) 2018, Texas Instruments Incorporated - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of Texas Instruments Incorporated nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/** + * These arguments were used when this file was generated. They will be automatically applied on subsequent loads + * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments. + * @cliArgs --board "/ti/boards/LP_EM_CC1354P10_1" --product "simplelink_cc13xx_cc26xx_sdk@7.10.00.98" + * @versions {"tool":"1.16.2+3028"} */ -/* - * cli_ftd.syscfg +/** + * Import the modules used in this configuration. */ - -/* Modules */ -var AESECB = scripting.addModule("/ti/drivers/AESECB"); -var DMA = scripting.addModule("/ti/drivers/DMA"); -var Device = scripting.addModule("/ti/devices/CCFG"); -var ECDH = scripting.addModule("/ti/drivers/ECDH"); -var ECDSA = scripting.addModule("/ti/drivers/ECDSA"); -var ECJPAKE = scripting.addModule("/ti/drivers/ECJPAKE"); -var GPIO = scripting.addModule("/ti/drivers/GPIO"); -var NVS = scripting.addModule("/ti/drivers/NVS"); -var Power = scripting.addModule("/ti/drivers/Power"); -var RF = scripting.addModule("/ti/drivers/RF"); -var RFCustom = scripting.addModule("/ti/devices/radioconfig/custom"); -var RFDesign = scripting.addModule("ti/devices/radioconfig/rfdesign"); -var SHA2 = scripting.addModule("/ti/drivers/SHA2"); -var SPI = scripting.addModule("/ti/drivers/SPI"); -var TRNG = scripting.addModule("/ti/drivers/TRNG"); -var UART2 = scripting.addModule("/ti/drivers/UART2"); -var Watchdog = scripting.addModule("/ti/drivers/Watchdog"); - - -/* Instances */ -var AESECB = AESECB.addInstance(); -var ECDH = ECDH.addInstance(); -var ECDSA = ECDSA.addInstance(); -var ECJPAKE = ECJPAKE.addInstance(); -var GPIO1 = GPIO.addInstance(); -var GPIO2 = GPIO.addInstance(); -var GPIO3 = GPIO.addInstance(); -var GPIO4 = GPIO.addInstance(); -var GPIO5 = GPIO.addInstance(); -var NVS1 = NVS.addInstance(); -var SHA21 = SHA2.addInstance(); -var SPI2 = SPI.addInstance(); -var TRNG1 = TRNG.addInstance(); -var UART2 = UART2.addInstance(); -var Watchdog1 = Watchdog.addInstance(); - -const deviceId = system.deviceData.deviceId; - - -/* TI SimpleLink FreeRTOS configuration and build is not possible until - * configTICK_RATE_HZ is configurable and source directory set correctly. - * - * Only generate the kernel configuration for tirtos7 for now. +const ble = scripting.addModule("/ti/ble5stack/ble"); +const CCFG = scripting.addModule("/ti/devices/CCFG"); +const custom = scripting.addModule("/ti/devices/radioconfig/custom"); +const rfdesign = scripting.addModule("/ti/devices/radioconfig/rfdesign"); +const Display = scripting.addModule("/ti/display/Display", {}, false); +const Display1 = Display.addInstance(); +const dmm = scripting.addModule("/ti/dmm/dmm"); +const AESCCM = scripting.addModule("/ti/drivers/AESCCM", {}, false); +const AESCCM1 = AESCCM.addInstance(); +const AESCTRDRBG = scripting.addModule("/ti/drivers/AESCTRDRBG", {}, false); +const AESCTRDRBG1 = AESCTRDRBG.addInstance(); +const AESECB = scripting.addModule("/ti/drivers/AESECB"); +const AESECB1 = AESECB.addInstance(); +const DMA = scripting.addModule("/ti/drivers/DMA"); +const ECDH = scripting.addModule("/ti/drivers/ECDH"); +const ECDH1 = ECDH.addInstance(); +const ECDSA = scripting.addModule("/ti/drivers/ECDSA"); +const ECDSA1 = ECDSA.addInstance(); +const ECJPAKE = scripting.addModule("/ti/drivers/ECJPAKE"); +const ECJPAKE1 = ECJPAKE.addInstance(); +const GPIO = scripting.addModule("/ti/drivers/GPIO"); +const GPIO1 = GPIO.addInstance(); +const GPIO2 = GPIO.addInstance(); +const GPIO3 = GPIO.addInstance(); +const GPIO4 = GPIO.addInstance(); +const GPIO5 = GPIO.addInstance(); +const NVS = scripting.addModule("/ti/drivers/NVS"); +const NVS1 = NVS.addInstance(); +const Power = scripting.addModule("/ti/drivers/Power"); +const RF = scripting.addModule("/ti/drivers/RF"); +const SHA2 = scripting.addModule("/ti/drivers/SHA2"); +const SHA21 = SHA2.addInstance(); +const SPI = scripting.addModule("/ti/drivers/SPI"); +const SPI1 = SPI.addInstance(); +const TRNG = scripting.addModule("/ti/drivers/TRNG"); +const TRNG1 = TRNG.addInstance(); +const UART2 = scripting.addModule("/ti/drivers/UART2"); +const Watchdog = scripting.addModule("/ti/drivers/Watchdog"); +const Watchdog1 = Watchdog.addInstance(); + +/** + * Write custom configuration values to the imported modules. + */ +ble.radioConfig.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param1"; +ble.connUpdateParamsPeripheral.$name = "ti_ble5stack_general_ble_conn_update_params0"; +ble.advSet1.$name = "ti_ble5stack_broadcaster_advertisement_set0"; +ble.advSet1.advParam1.$name = "ti_ble5stack_broadcaster_advertisement_params0"; +ble.advSet1.advData1.$name = "ti_ble5stack_broadcaster_advertisement_data0"; +ble.advSet1.advData1.GAP_ADTYPE_LOCAL_NAME_SHORT = true; +ble.advSet1.advData1.shortenedLocalName = "SP"; +ble.advSet1.advData1.GAP_ADTYPE_FLAGS = true; +ble.advSet1.advData1.advertisingFlags = ["GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED"]; +ble.advSet1.advData1.GAP_ADTYPE_16BIT_MORE = true; +ble.advSet1.advData1.numOfUUIDs16More = 1; +ble.advSet1.advData1.UUID016More = 0xFFF0; +ble.advSet1.scanRes1.$name = "ti_ble5stack_broadcaster_advertisement_data1"; +ble.advSet1.scanRes1.GAP_ADTYPE_LOCAL_NAME_COMPLETE = true; +ble.advSet1.scanRes1.GAP_ADTYPE_POWER_LEVEL = true; +ble.advSet1.scanRes1.GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE = true; +ble.advSet1.scanRes1.maxConnInterval = 130; +ble.advSet2.$name = "ti_ble5stack_broadcaster_advertisement_set1"; +ble.advSet2.advParam2.$name = "ti_ble5stack_broadcaster_advertisement_params1"; +ble.advSet2.advData2.$name = "ti_ble5stack_broadcaster_advertisement_data2"; +ble.advSet2.advData2.GAP_ADTYPE_LOCAL_NAME_SHORT = true; +ble.advSet2.advData2.shortenedLocalName = "SP"; +ble.advSet2.advData2.GAP_ADTYPE_FLAGS = true; +ble.advSet2.advData2.advertisingFlags = ["GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED"]; +ble.advSet2.advData2.GAP_ADTYPE_16BIT_MORE = true; +ble.advSet2.advData2.numOfUUIDs16More = 1; +ble.advSet2.advData2.UUID016More = 0xFFF0; +ble.advSet2.scanRes2.$name = "ti_ble5stack_broadcaster_advertisement_data3"; + +CCFG.xoscCapArray = true; +CCFG.xoscCapArrayDelta = 0xD5; +CCFG.enableBootloader = true; +CCFG.dioBootloaderBackdoor = 15; +CCFG.levelBootloaderBackdoor = "Active low"; +CCFG.srcClkLF = "Derived from HF XOSC"; +CCFG.ccfgTemplate.$name = "ti_devices_CCFG_CCFGCC26XXTemplate0"; + +custom.ieee = ["ieee154"]; +custom.radioConfigieee154.$name = "ti_devices_radioconfig_settings_ieee_15_40"; +custom.radioConfigieee154.codeExportConfig.$name = "ti_devices_radioconfig_code_export_param0"; +custom.radioConfigieee154.codeExportConfig.useConst = true; +custom.radioConfigieee154.codeExportConfig.useMulti = true; +custom.radioConfigieee154.codeExportConfig.symGenMethod = "Custom"; +custom.radioConfigieee154.codeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; +custom.radioConfigieee154.codeExportConfig.cmdList_ieee_15_4 = ["cmdIeeeCsma","cmdIeeeEdScan","cmdIeeeRx","cmdIeeeRxAck","cmdIeeeTx","cmdRadioSetupPa","cmdTxTest"]; + +rfdesign.rfDesign = "LP_EM_CC1354P10_1"; + +Display1.$name = "CONFIG_Display_0"; +Display1.uart.$name = "CONFIG_DISPLAY_UART"; +Display1.uart.$hardware = system.deviceData.board.components.XDS110UART; + +dmm.stackRoles = ["blePeripheral","custom1"]; +dmm.policyArray[0].$name = "ti_dmm_policy_dmm_policy0"; +dmm.policyArray[0].custom1.$name = "ti_dmm_policy_stack_dmm_stack_custom0"; +dmm.policyArray[0].blePeripheral.$name = "ti_dmm_policy_stack_dmm_stack_ble0"; +dmm.policyArray[0].blePeripheral.weight = 1; + +AESCCM1.$name = "CONFIG_AESCCM_0"; + +AESCTRDRBG1.$name = "CONFIG_AESCTRDRBG_0"; + +AESECB1.$name = "CONFIG_AESECB_MBEDTLS"; + +ECDH1.$name = "CONFIG_ECDH_0"; + +ECDSA1.$name = "CONFIG_ECDSA_0"; + +ECJPAKE1.$name = "CONFIG_ECJPAKE_0"; + +GPIO1.$hardware = system.deviceData.board.components["BTN-1"]; +GPIO1.$name = "CONFIG_GPIO_BTN1"; + +GPIO2.$hardware = system.deviceData.board.components["BTN-2"]; +GPIO2.$name = "CONFIG_GPIO_BTN2"; + +GPIO3.$hardware = system.deviceData.board.components.LED_GREEN; +GPIO3.$name = "CONFIG_GPIO_GLED"; + +GPIO4.$hardware = system.deviceData.board.components.LED_RED; +GPIO4.$name = "CONFIG_GPIO_RLED"; + +GPIO5.$name = "CONFIG_SPINEL_INT"; +GPIO5.mode = "Output"; +GPIO5.outputStrength = "High"; +GPIO5.initialOutputState = "High"; +GPIO5.gpioPin.$assign = "boosterpack.32"; + +NVS1.$name = "CONFIG_NVSINTERNAL"; +NVS1.internalFlash.$name = "ti_drivers_nvs_NVSCC26XX0"; +NVS1.internalFlash.regionBase = 0x52000; +NVS1.internalFlash.regionSize = 0x4000; + +RF.$hardware = system.deviceData.board.components["SKY13317-373LF"]; + +SHA21.$name = "CONFIG_SHA2_0"; + +SPI1.$name = "CONFIG_SPI_1"; +SPI1.mode = "Four Pin CS Active Low"; +SPI1.spi.sclkPin.$assign = "boosterpack.24"; +SPI1.spi.pociPin.$assign = "boosterpack.6"; +SPI1.spi.picoPin.$assign = "boosterpack.23"; +SPI1.spi.csnPin.$assign = "boosterpack.25"; + +TRNG1.$name = "CONFIG_TRNG_THREAD"; + +Watchdog1.$name = "CONFIG_WATCHDOG0"; +Watchdog1.watchdog.$assign = "WDT0"; + +/** + * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future + * version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to + * re-solve from scratch. */ -/* Kernel Configuration */ -if (system.getRTOS() === "tirtos7") { - system.getScript("kernel_config_release.syscfg.js"); -} - - -/* CCFG */ -const ccfgSettings = system.getScript("/ti/common/lprf_ccfg_settings.js").ccfgSettings; -for(var setting in ccfgSettings) -{ - Device[setting] = ccfgSettings[setting]; -} - -Device.srcClkLF = "Derived from HF XOSC"; - - -/* UART */ -UART2.$hardware = system.deviceData.board.components.XDS110UART; -UART2.$name = "CONFIG_UART2_0"; - - -/* GPIO */ -GPIO1.$hardware = system.deviceData.board.components["BTN-1"]; -GPIO1.$name = "CONFIG_GPIO_BTN1"; - -GPIO2.$hardware = system.deviceData.board.components["BTN-2"]; -GPIO2.$name = "CONFIG_GPIO_BTN2"; - -GPIO3.$hardware = system.deviceData.board.components.LED_GREEN; -GPIO3.$name = "CONFIG_GPIO_GLED"; - -GPIO4.$hardware = system.deviceData.board.components.LED_RED; -GPIO4.$name = "CONFIG_GPIO_RLED"; - - -/* SPI for NCP */ -SPI2.$name = "CONFIG_SPI_1"; -SPI2.mode = "Four Pin SS Active Low"; -SPI2.spi.pociPin.$assign = "DIO24" -SPI2.spi.picoPin.$assign = "DIO25" -SPI2.spi.sclkPin.$assign = "DIO26" -SPI2.spi.csnPin.$assign = "DIO27" - -GPIO5.$name = "CONFIG_SPINEL_INT"; -GPIO5.mode = "Output"; -GPIO5.outputStrength = "High"; -GPIO5.initialOutputState = "High"; -GPIO5.gpioPin.$assign = "DIO16"; - - -/* NVS */ -NVS1.$name = "CONFIG_NVSINTERNAL"; - -/* place at the end of Flash */ -if(deviceId.match(/CC((13|26).2(R|RB|P)7)/)) -{ - NVS1.internalFlash.regionBase = 0xAA000; - NVS1.internalFlash.regionSize = 0x4000; -} -else if(deviceId.match(/CC((13|26).2(R|RB|P)1)/)) -{ - NVS1.internalFlash.regionBase = 0x52000; - NVS1.internalFlash.regionSize = 0x4000; -} -else if(deviceId.match(/CC((13|26).4P10)/)) -{ - NVS1.internalFlash.regionBase = 0x52000; - NVS1.internalFlash.regionSize = 0x4000; -} -else -{ - throw new Error("Could not set NVS location for deviceId: " + deviceId); -} - - -/* Watchdog */ -Watchdog1.$name = "CONFIG_WATCHDOG0"; -Watchdog1.period = 1000; -Watchdog1.watchdog.$assign = "WDT0"; - -/* TRNG */ -TRNG1.$name = "CONFIG_TRNG_THREAD"; - -/* AES */ -AESECB.$name = "CONFIG_AESECB_MBEDTLS"; - -/* RF */ - -/* if an antenna component exists, assign it to the rf instance */ -if (system.deviceData.board && system.deviceData.board.components.RF) { - RF.$hardware = system.deviceData.board.components.RF; -} - -const rfDesignSettings = system.getScript("/ti/common/lprf_rf_design_settings.js").rfDesignSettings; -for(var setting in rfDesignSettings) -{ - RFDesign[setting] = rfDesignSettings[setting]; -} - -/* Handling for RF frontend characterization */ -if(RFDesign.rfDesign.match(/LP_CC2652PSIP/)) -{ - RFCustom.ieee = ["ieee154p10"]; - var rfCodeExportConfig = RFCustom.radioConfigieee154p10.codeExportConfig -} -else -{ - RFCustom.ieee = ["ieee154"]; - var rfCodeExportConfig = RFCustom.radioConfigieee154.codeExportConfig -} - -var cmdList = [ - "cmdIeeeTx", - "cmdIeeeRx", - "cmdIeeeCsma", - "cmdIeeeEdScan", - "cmdIeeeRxAck", - "cmdTxTest" -]; - -rfCodeExportConfig.useConst = true; -rfCodeExportConfig.useMulti = true; -rfCodeExportConfig.symGenMethod = "Custom"; - -// Add high PA options if present -if(deviceId.match(/CC(265[12]R|2674R|1352R1|1354R)/)) -{ - cmdList.push("cmdRadioSetup"); - rfCodeExportConfig.cmdRadioSetup = "RF_cmdIeeeRadioSetup"; -} -else if(deviceId.match(/CC(265[12]P|2674P|1352P)/)) -{ - cmdList.push("cmdRadioSetupPa"); - rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; - rfCodeExportConfig.paExport = "combined"; -} -else if(deviceId.match(/CC(265[34]|1354)P/)) -{ - cmdList.push("cmdRadioSetupPa"); - rfCodeExportConfig.cmdRadioSetupPa = "RF_cmdIeeeRadioSetup"; - // currently not characterized for high PA -} -else -{ - throw new Error("Could not set RF settings for deviceId: " + deviceId); -} - -rfCodeExportConfig.cmdList_ieee_15_4 = cmdList; +Display1.uart.uart.$suggestSolution = "UART0"; +Display1.uart.uart.txPin.$suggestSolution = "boosterpack.4"; +Display1.uart.uart.rxPin.$suggestSolution = "boosterpack.3"; +GPIO1.gpioPin.$suggestSolution = "boosterpack.11"; +GPIO2.gpioPin.$suggestSolution = "boosterpack.17"; +GPIO3.gpioPin.$suggestSolution = "DIO_7"; +GPIO4.gpioPin.$suggestSolution = "DIO_6"; +RF.rfAntennaPin0.$suggestSolution = "DIO_34"; +RF.rfAntennaPin1.$suggestSolution = "DIO_3"; +RF.rfAntennaPin2.$suggestSolution = "DIO_35"; +SPI1.spi.$suggestSolution = "SPI0"; +SPI1.spi.dmaRxChannel.$suggestSolution = "DMA_CH3"; +SPI1.spi.dmaTxChannel.$suggestSolution = "DMA_CH4"; diff --git a/src/uart.c b/src/uart.c index 30faf1c..ccbcdb4 100644 --- a/src/uart.c +++ b/src/uart.c @@ -112,7 +112,7 @@ otError otPlatUartEnable(void) params.writeCallback = uartWriteCallback; #endif - PlatformUart_uartHandle = UART2_open(CONFIG_UART2_0, ¶ms); + PlatformUart_uartHandle = UART2_open(CONFIG_DISPLAY_UART, ¶ms); UART2_read(PlatformUart_uartHandle, PlatformUart_receiveBuffer, sizeof(PlatformUart_receiveBuffer), NULL); diff --git a/third_party/freertos/CMakeLists.txt b/third_party/freertos/CMakeLists.txt index 2ee0167..bbc7727 100644 --- a/third_party/freertos/CMakeLists.txt +++ b/third_party/freertos/CMakeLists.txt @@ -43,7 +43,7 @@ set(FREERTOS_SRCS if(TI_SIMPLELINK_ISA STREQUAL "m4f") set(FREERTOS_PORT_SRCS - ${CMAKE_CURRENT_SOURCE_DIR}/repo/portable/MemMang/heap_4.c + #${CMAKE_CURRENT_SOURCE_DIR}/repo/portable/MemMang/heap_4.c ${CMAKE_CURRENT_SOURCE_DIR}/repo/portable/GCC/ARM_CM4F/port.c ) @@ -53,7 +53,7 @@ if(TI_SIMPLELINK_ISA STREQUAL "m4f") elseif(TI_SIMPLELINK_ISA STREQUAL "m33f") set(FREERTOS_PORT_SRCS - ${CMAKE_CURRENT_SOURCE_DIR}/repo/portable/MemMang/heap_4.c + #${CMAKE_CURRENT_SOURCE_DIR}/repo/portable/MemMang/heap_4.c ${CMAKE_CURRENT_SOURCE_DIR}/repo/portable/GCC/ARM_CM33_NTZ/non_secure/port.c ${CMAKE_CURRENT_SOURCE_DIR}/repo/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c )