1 /***************************************************************************//**
2 * \file cy_ble.c
3 * \version 3.60
4 *
5 * \brief
6 * This file contains the source code for the API of the PSoC 6 BLE Middleware.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2017-2021, Cypress Semiconductor Corporation. All rights reserved.
11 * You may use this file only in accordance with the license, terms, conditions,
12 * disclaimers, and limitations in the end user license agreement accompanying
13 * the software package with which this file was provided.
14 *******************************************************************************/
15
16 #include <stdint.h>
17 #include "cy_ble_event_handler.h"
18 #include "cy_ble_hal_pvt.h"
19 #include "cy_ble.h"
20
21 #include "cy_ble_stack_pvt.h"
22
23 #if defined(CY_IP_MXBLESS)
24
25 #ifdef CY_BLE_WARNING_NO_SELECTED_BLESS_COMPONENTS
26 #warning The BLE Stack components are not defined in Makefile. Use COMPONENTS variable in Makefile \
27 to select BLE Stack component. The following COMPONENTS define patricular BLE Stack modes: \
28 'COMPONENTS+=BLESS_HOST_IPC CM0_BLESS' - to operate in dual CPU mode, \
29 'COMPONENTS+=BLESS_CONTROLLER BLESS_HOST' - to operate in single CPU mode, \
30 'COMPONENTS+=BLESS_CONTROLLER' - to operate in controller only (HCI) mode. \
31 /* For more details refer to the following documentation:
32 * https://cypresssemiconductorco.github.io/bless/ble_api_reference_manual/html/page_ble_section_configuration_considerations.html#group_ble_section_conf_cons_prebuild */
33 #endif /* ifdef WARNING_NO_SELECTED_BLESS_COMPONENT */
34
35 /*******************************************************************************
36 * Private Function Prototypes
37 *******************************************************************************/
38
39 static void Cy_BLE_RegisterPmCallbacksSingle(void);
40 static void Cy_BLE_RegisterPmCallbacksDual(void);
41
42 static void Cy_BLE_UnregisterHostPmCallbacksSingle(void);
43 static void Cy_BLE_UnregisterHostPmCallbacksDual(void);
44
45 static cy_en_syspm_status_t Cy_BLE_DeepSleepCallbackSingleCore(cy_stc_syspm_callback_params_t *callbackParams,
46 cy_en_syspm_callback_mode_t mode);
47 static cy_en_syspm_status_t Cy_BLE_DeepSleepCallbackDualCore(cy_stc_syspm_callback_params_t *callbackParams,
48 cy_en_syspm_callback_mode_t mode);
49 static cy_en_syspm_status_t Cy_BLE_SleepCallbackDualCore(cy_stc_syspm_callback_params_t *callbackParams,
50 cy_en_syspm_callback_mode_t mode);
51
52
53 /*******************************************************************************
54 * Global Variables
55 *******************************************************************************/
56
57 /** An application layer event callback function to receive
58 * service events from the PSoC 6 BLE Middleware. */
59 cy_ble_callback_t Cy_BLE_ApplCallback = NULL;
60
61 /** Pointer to the global BLE configuration structures */
62 __WEAK const cy_stc_ble_config_t *cy_ble_configPtr = NULL;
63
64 /** Pointers to SysPm callback function */
65 void (*Cy_BLE_RegisterPmCallbacksPtr)(void) = NULL;
66 void (*Cy_BLE_UnregisterPmCallbacksPtr)(void) = NULL;
67
68 /* Structure with the SysPm callback parameters for BLESS deep sleep */
69 static cy_stc_syspm_callback_params_t bleDeepSleepCallbackParams =
70 {
71 /* base */ NULL,
72 /* context */ NULL
73 };
74
75 static cy_stc_syspm_callback_t bleDeepSleepCallback =
76 {
77 /* callback */ NULL,
78 /* type */ CY_SYSPM_DEEPSLEEP,
79 /* skipMode */ CY_SYSPM_SKIP_BEFORE_TRANSITION | CY_SYSPM_SKIP_CHECK_FAIL,
80
81 /* callbackParams */ &bleDeepSleepCallbackParams,
82 /* prevItm */ NULL,
83 /* nextItm */ NULL,
84 /* order */ CY_BLE_LPM_SYSPM_CB_ORDER
85 };
86
87 /* Structure with the SysPm callback parameters for BLE sleep */
88 static cy_stc_syspm_callback_params_t bleSleepCallbackParams =
89 {
90 /* base */ NULL,
91 /* context */ NULL
92 };
93
94 static cy_stc_syspm_callback_t bleSleepCallback =
95 {
96 /* callback */ &Cy_BLE_SleepCallbackDualCore,
97 /* type */ CY_SYSPM_SLEEP,
98 /* skipMode */ CY_SYSPM_SKIP_BEFORE_TRANSITION | CY_SYSPM_SKIP_CHECK_FAIL,
99
100 /* callbackParams */ &bleSleepCallbackParams,
101 /* prevItm */ NULL,
102 /* nextItm */ NULL,
103 /* order */ CY_BLE_LPM_SYSPM_CB_ORDER
104 };
105
106
107 /******************************************************************************
108 * Function Name: Cy_BLE_InitHost
109 ***************************************************************************//**
110 *
111 * Initializes the PSoC 6 BLE Middleware (Host part).
112 *
113 * \param config: The configuration structure for the PSoC 6 BLE Middleware.
114 *
115 * \return
116 * \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
117 * failed. The following are possible error codes.
118 *
119 * Error codes | Description
120 * ------------ | -----------
121 * CY_BLE_SUCCESS | The function completed successfully.
122 * CY_BLE_ERROR_INVALID_PARAMETER | On specifying NULL as the input parameter.
123 *
124 ******************************************************************************/
Cy_BLE_InitHost(const cy_stc_ble_config_t * config)125 cy_en_ble_api_result_t Cy_BLE_InitHost(const cy_stc_ble_config_t *config)
126 {
127 cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
128
129 #if CY_BLE_LIB_HOST_CORE
130 if((config == NULL) || (Cy_BLE_ApplCallback == NULL))
131 {
132 apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
133 }
134 else
135 {
136 uint32_t idx;
137
138 /* Register a pointer to the configuration structure */
139 cy_ble_configPtr = config;
140 Cy_BLE_HAL_SetConfigStructure(cy_ble_configPtr);
141
142 /* Initializes cy_ble_connHandle */
143 for(idx = 0u; idx < CY_BLE_MAX_SUPPORTED_CONN_COUNT; idx++)
144 {
145 cy_ble_connHandle[idx].bdHandle = CY_BLE_INVALID_CONN_HANDLE_VALUE;
146 cy_ble_connHandle[idx].attId = CY_BLE_INVALID_CONN_HANDLE_VALUE;
147 }
148
149 /* Initializes client structures */
150 if((cy_ble_configPtr->params->gattRole & CY_BLE_GATT_CLIENT) != 0u)
151 {
152 for(idx = 0u; idx < cy_ble_configPtr->params->maxClientCount; idx++)
153 {
154 uint32 servCnt = cy_ble_configPtr->context->discServiCount;
155 (void)memset(&cy_ble_configPtr->context->serverInfo[idx * servCnt], 0,
156 (sizeof(cy_stc_ble_disc_srvc_info_t) * servCnt));
157 (void)memset(&cy_ble_configPtr->context->discovery[idx], 0, sizeof(cy_stc_ble_discovery_t));
158
159 /* Update cy_ble_discovery[].connIndex with init values (CY_BLE_INVALID_CONN_HANDLE_VALUE) */
160 cy_ble_configPtr->context->discovery[idx].connIndex = CY_BLE_INVALID_CONN_HANDLE_VALUE;
161 }
162 }
163
164 if(cy_ble_configPtr->ServiceInitFunc != NULL)
165 {
166 cy_ble_configPtr->ServiceInitFunc();
167 }
168
169 cy_ble_pendingFlashWrite = 0u;
170 cy_ble_eventHandlerFlag = 0u;
171 (void)memset(cy_ble_peerBonding, (int8_t)CY_BLE_GAP_BONDING_NONE, sizeof(cy_ble_peerBonding));
172
173 }
174 #else
175 /* Suppress unused variable warning */
176 (void) config;
177 #endif /* CY_BLE_LIB_HOST_CORE */
178 return(apiResult);
179 }
180
181
182 /******************************************************************************
183 * Function Name: Cy_BLE_EnableHost
184 ***************************************************************************//**
185 *
186 * This function initializes the BLE Stack, which consists of the BLE Stack
187 * Manager, BLE Controller, and BLE Host modules. It takes care of initializing
188 * the Profile layer, schedulers, Timer, and other platform-related resources
189 * required for the PSoC 6 BLE Middleware.
190 *
191 * Note that this function does not reset the BLE Stack.
192 *
193 * Calling this function results in generation of a #CY_BLE_EVT_STACK_ON event
194 * on successful initialization of the BLE Stack.
195 *
196 * In the BLE dual CPU mode, this function should be called on Host cores.
197 *
198 * The BLE Stack enables the BLE ECO clock automatically with the default
199 * parameters:
200 * Parameter | Value
201 * -------------------- | -----------
202 * ECO Frequency | CY_BLE_DEFAULT_ECO_FREQ
203 * Divider | CY_BLE_DEFAULT_ECO_DIV
204 * Startup time | CY_BLE_DEFAULT_OSC_STARTUP_DELAY_LF
205 * Load cap | CY_BLE_DEFAULT_CAP_TRIM_VALUE
206 *
207 * If there is a need to start the BLE with non-default ECO parameters,
208 * call the Cy_BLE_EcoConfigure() function with the custom configuration each
209 * time before calling the Cy_BLE_EnableHost() function.
210 *
211 * NOTE: BLE requires a call to Cy_IPC_SystemSemaInit() and Cy_IPC_SystemPipeInit()
212 * functions before use.
213 * This function is called in the SystemInit() function for proper flash write
214 * and erase operations. If the default startup file is not used, or the function
215 * SystemInit() is not called in your project, call the following functions:
216 * -# Cy_IPC_SystemSemaInit()
217 * -# Cy_IPC_SystemPipeInit()
218 *
219 * return
220 * \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded
221 * or failed. The following are possible error codes.
222 *
223 * <table>
224 * <tr>
225 * <th>Error codes</th>
226 * <th>Description</th>
227 * </tr>
228 * <tr>
229 * <td>CY_BLE_SUCCESS</td>
230 * <td>On successful operation.</td>
231 * </tr>
232 * <tr>
233 * <td>CY_BLE_ERROR_REPEATED_ATTEMPTS</td>
234 * <td>On invoking this function more than once without calling
235 * Cy_BLE_Disable() function between calls to this function.</td>
236 * </tr>
237 * <tr>
238 * <td>CY_BLE_ERROR_MEMORY_ALLOCATION_FAILED</td>
239 * <td>There is insufficient memory available.</td>
240 * </tr>
241 * <tr>
242 * <td>CY_BLE_ERROR_INVALID_STATE</td>
243 * <td>The PSoC 6 BLE Middleware was not initialized.</td>
244 * </tr>
245 * </table>
246 *
247 ******************************************************************************/
Cy_BLE_EnableHost(void)248 cy_en_ble_api_result_t Cy_BLE_EnableHost(void)
249 {
250 cy_en_ble_api_result_t apiResult = CY_BLE_ERROR_INVALID_STATE;
251
252 #if CY_BLE_LIB_HOST_CORE
253 if (cy_ble_configPtr != NULL)
254 {
255 /* Set of buffers to be allocated by the BLE Stack for BLE Stack operation */
256 /* Array dataBuff [totalDataBufferPools] shall provide the information to the BLE Stack based
257 * on the below table:
258 *
259 * Index | bufferSize | noOfBuffer
260 * ----- | --------------------------------------------------------| ---------------
261 * 0 | (GATT MTU + CY_BLE_MEM_EXT_SZ + CY_BLE_L2CAP_HDR_SZ) | 3
262 * 1 | ((CY_BLE_L2CAP_PSM_SIZE + CY_BLE_MEM_EXT_SZ) * | No of PSM supported
263 * | No of PSM supported) |
264 * | |
265 * 2 | ((CY_BLE_L2CAP_CBFC_CHANNEL_SIZE + CY_BLE_MEM_EXT_SZ) * | 2 * No of L2cap
266 * | No of L2CAP logical channels) | logical channels
267 * | |
268 * 3 | (L2CAP MTU + CY_BLE_MEM_EXT_SZ + CY_BLE_L2CAP_HDR_SZ) | 2 * No of L2cap
269 * | | logical channels
270 */
271
272 /* Data Buffer information for ATT/GATT Configured MTU Size */
273 uint16_t dataBuffIdx0 = CY_BLE_ALIGN_TO_4(cy_ble_configPtr->params->mtuSize +
274 CY_BLE_MEM_EXT_SZ + CY_BLE_L2CAP_HDR_SZ);
275
276 /* Data Buffer information forL2CAP configuration for number of PSM Channels */
277 uint16_t dataBuffIdx1 = CY_BLE_ALIGN_TO_4(cy_ble_configPtr->params->l2capPsmCount *
278 (CY_BLE_L2CAP_PSM_SIZE + CY_BLE_MEM_EXT_SZ));
279
280 /* Data Buffer information for L2CAP configuration for number of CBFC Channels */
281 uint16_t dataBuffIdx2 = CY_BLE_ALIGN_TO_4(cy_ble_configPtr->params->l2capChanCount *
282 (CY_BLE_L2CAP_CBFC_CHANNEL_SIZE + CY_BLE_MEM_EXT_SZ));
283
284 /* Data Buffer information for L2CAP configured MTU Size */
285 uint16_t dataBuffIdx3 = CY_BLE_ALIGN_TO_4(cy_ble_configPtr->params->l2capMtuSize +
286 CY_BLE_MEM_EXT_SZ + CY_BLE_L2CAP_HDR_SZ);
287
288 #if defined(CY_BLE_STACK_APP_POOL_5_SZ)
289 /* Data Buffer information for GATT DB maximum entry Size */
290 uint16_t dbInxCount = cy_ble_configPtr->params->gattDbIndexCount;
291 uint16_t dataBuffIdx4 = CY_BLE_ALIGN_TO_4((dbInxCount / 8u) + CY_BLE_MEM_EXT_SZ +
292 (((dbInxCount % 8u) != 0u) ? 1u : 0u )) ;
293 #endif /* defined(CY_BLE_STACK_APP_POOL_5_SZ) */
294
295 /* If mtu > 23 stack queue depth (stack queue depth per connection - 1) * maxBleConnection */
296 uint16_t mtuBuffCount = (cy_ble_configPtr->stackParam->maxConnCount *
297 ((cy_ble_configPtr->params->mtuSize > CY_BLE_MTU_MIN_VALUE) ?
298 ((uint16_t)cy_ble_configPtr->stackParam->l2capBufferPerConn - 1u) :
299 CY_BLE_MTU_MIN_BUFF_NUM));
300
301 cy_stc_ble_stk_app_data_buff_t stackDataBuff[CY_BLE_STACK_APP_MIN_POOL] =
302 {
303 { dataBuffIdx0, mtuBuffCount },
304 { dataBuffIdx1, cy_ble_configPtr->params->l2capPsmCount },
305 { dataBuffIdx2, 2u * cy_ble_configPtr->params->l2capChanCount },
306 { dataBuffIdx3, 2u * cy_ble_configPtr->params->l2capChanCount },
307 #if defined(CY_BLE_STACK_APP_POOL_5_SZ)
308 { dataBuffIdx4, 1u },
309 #endif /* defined(CY_BLE_STACK_APP_POOL_5_SZ) */
310 };
311
312 cy_stc_ble_stack_init_info_t stackInitParam;
313 (void)memset(&stackInitParam, 0, sizeof(cy_stc_ble_stack_init_info_t));
314
315 /* Application Callback Function */
316 stackInitParam.CyBleAppCbFunc = (cy_ble_app_ev_cb_t)&Cy_BLE_EventHandler;
317
318 /* Initialize BLE stack buffers needed for BLE Stack operation */
319 stackInitParam.memParam.dataBuff = stackDataBuff;
320
321 /* Total data buffer pools */
322 stackInitParam.memParam.totalDataBufferPools = CY_BLE_STACK_APP_MIN_POOL;
323
324 /* Flash storage */
325 if(cy_ble_configPtr->flashStorage->stackFlashPtr != NULL)
326 {
327 stackInitParam.memParam.bleStackFlashPointer = cy_ble_configPtr->flashStorage->stackFlashPtr;
328 stackInitParam.memParam.bleStackFlashSize = cy_ble_configPtr->flashStorage->stackFlashSize;
329 }
330
331 /* Configure l2cap queue */
332 stackInitParam.stackConfig.l2capConfig.l2capBufferPerConn = cy_ble_configPtr->stackParam->l2capBufferPerConn;
333
334 /* BLE Stack memory heap size */
335 stackInitParam.memParam.totalHeapSz = cy_ble_configPtr->stackParam->totalHeapSz;
336
337 /* Configure DLE */
338 stackInitParam.stackConfig.dleConfig.dleMaxTxCapability = cy_ble_configPtr->stackParam->dleMaxTxCapability;
339 stackInitParam.stackConfig.dleConfig.dleMaxRxCapability = cy_ble_configPtr->stackParam->dleMaxRxCapability;
340
341 stackInitParam.stackConfig.dleConfig.dleNumTxBuffer = CY_BLE_LL_DEFAULT_NUM_ACL_TX_PACKETS;
342 stackInitParam.stackConfig.dleConfig.dleNumRxBuffer = CY_BLE_LL_DEFAULT_NUM_ACL_RX_PACKETS;
343
344 /* Configure BLE Stack features */
345 stackInitParam.stackConfig.featureMask =
346 cy_ble_configPtr->stackParam->featureMask;
347
348 /* Configure maximum connection support */
349 stackInitParam.stackConfig.maxBleConnections =
350 cy_ble_configPtr->stackParam->maxConnCount;
351
352 /* Configure bonded device list */
353 stackInitParam.stackConfig.bondListConfig.bondListSize =
354 cy_ble_configPtr->stackParam->maxBondedDevListSize;
355
356 /* Configure white list */
357 stackInitParam.stackConfig.whiteListConfig.whiteListSize =
358 cy_ble_configPtr->stackParam->maxWhiteListSize;
359
360 /* Configure LL Privacy */
361 stackInitParam.stackConfig.privacyConfig.resolvingListSize =
362 cy_ble_configPtr->stackParam->maxResolvableDevListSize;
363
364 /* Register SysPm callback for BLESS deep sleep support */
365 if (Cy_BLE_RegisterPmCallbacksPtr != NULL)
366 {
367 Cy_BLE_RegisterPmCallbacksPtr();
368 }
369
370 /* Configure BLE features */
371 /* Enable DLE code in the stack */
372 if((cy_ble_configPtr->stackParam->featureMask & CY_BLE_DLE_FEATURE_MASK) != 0u)
373 {
374 Cy_BLE_EnableDleFeature();
375 }
376
377 /* Enable LL Privacy code in the stack */
378 if((cy_ble_configPtr->stackParam->featureMask & CY_BLE_PRIVACY_1_2_FEATURE_MASK) != 0u)
379 {
380 Cy_BLE_EnablePrivacyFeature();
381 }
382
383 /* Enable PHY Update code in the stack */
384 if((cy_ble_configPtr->stackParam->featureMask & CY_BLE_PHY_UPDATE_FEATURE_MASK) != 0u)
385 {
386 Cy_BLE_EnablePhyUpdateFeature();
387 }
388 apiResult = Cy_BLE_StackSetFeatureConfig(&stackInitParam.stackConfig);
389
390
391 if(apiResult == CY_BLE_SUCCESS)
392 {
393 /* Set pointer to memory RAM buffer */
394 stackInitParam.memParam.memoryHeapPtr = cy_ble_configPtr->stackParam->memoryHeapPtr;
395
396 /* Configure parameter for Radio PA calibration */
397 if(cy_ble_configPtr->stackParam->paCalConfig != NULL)
398 {
399 stackInitParam.stackConfig.paCalConfig = *cy_ble_configPtr->stackParam->paCalConfig;
400 }
401
402 /* Initialize the BLE Stack */
403 apiResult = Cy_BLE_StackInit(&stackInitParam);
404 }
405
406 if(apiResult == CY_BLE_SUCCESS)
407 {
408 /* Initializes internal states */
409 Cy_BLE_SetState(CY_BLE_STATE_INITIALIZING);
410
411 if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_PERIPHERAL | CY_BLE_GAP_BROADCASTER)) != 0u)
412 {
413 Cy_BLE_SetAdvertisementState(CY_BLE_ADV_STATE_STOPPED);
414 }
415
416 if((cy_ble_configPtr->params->gapRole & (CY_BLE_GAP_OBSERVER | CY_BLE_GAP_CENTRAL)) != 0u)
417 {
418 Cy_BLE_SetScanState(CY_BLE_SCAN_STATE_STOPPED);
419 }
420 }
421 }
422 #endif /* CY_BLE_LIB_HOST_CORE */
423
424 return(apiResult);
425 }
426
427
428 /******************************************************************************
429 * Function Name: Cy_BLE_DisableHost
430 ***************************************************************************//**
431 *
432 * This function stops any ongoing operation in the BLE Stack and forces the
433 * BLE Stack to shut down.
434 *
435 * Calling this function results in generation of a
436 * #CY_BLE_EVT_STACK_SHUTDOWN_COMPLETE event on a successful stack shut-down.
437
438 *
439 * \return
440 * \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded or
441 * failed. The following are possible error codes.
442 *
443 * <table>
444 * <tr>
445 * <th>Error codes</th>
446 * <th>Description</th>
447 * </tr>
448 * <tr>
449 * <td>CY_BLE_SUCCESS</td>
450 * <td>On successful operation.</td>
451 * </tr>
452 * <tr>
453 * <td>CY_BLE_ERROR_INVALID_OPERATION</td>
454 * <td>On calling Cy_BLE_Disable before calling Cy_BLE_Enable()
455 * or on Controller core.</td>
456 * </tr>
457 * </table>
458 *
459 ******************************************************************************/
Cy_BLE_DisableHost(void)460 cy_en_ble_api_result_t Cy_BLE_DisableHost(void)
461 {
462 cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
463
464 #if CY_BLE_LIB_HOST_CORE
465 /* Stops all ongoing activities */
466 apiResult = Cy_BLE_StackShutdown();
467 #endif /* CY_BLE_LIB_HOST_CORE */
468
469 return(apiResult);
470 }
471
472
473 /******************************************************************************
474 * Function Name: Cy_BLE_RegisterEventCallback
475 ***************************************************************************//**
476 *
477 * Registers a callback function to receive events from the PSoC 6 BLE Middleware.
478 *
479 * \param callbackFunc: An application layer event callback function to receive
480 * events from the PSoC 6 BLE Middleware. The definition of \ref cy_ble_callback_t
481 * is:<br>
482 * typedef void (* cy_ble_callback_t) (uint32_t eventCode, void *eventParam),
483 * where:
484 * * eventCode: Indicates the event that triggered this callback
485 * (e.g. #CY_BLE_EVT_STACK_ON).
486 * * eventParam: Contains the parameters corresponding to the
487 * current event.
488 *
489 ******************************************************************************/
Cy_BLE_RegisterEventCallback(cy_ble_callback_t callbackFunc)490 void Cy_BLE_RegisterEventCallback(cy_ble_callback_t callbackFunc)
491 {
492 /* Store an application callback function */
493 Cy_BLE_ApplCallback = callbackFunc;
494 }
495
496
497 /*******************************************************************************
498 * Function Name: Cy_BLE_RegisterInterruptCallback
499 ****************************************************************************//**
500 *
501 * This function registers a callback to expose BLE interrupt notifications to an
502 * application that indicates a different link layer and radio state transition
503 * to the user from the BLESS interrupt context. This callback is triggered at
504 * the beginning of a received BLESS interrupt (based on the registered
505 * interrupt mask).
506 *
507 * An application can use an interrupt callback to know when:
508 * * the RF activity is about to begin/end;
509 * * the BLE device changes its state from advertising to connected;
510 * * BLESS transits between BLESS active and BLESS low-power modes.
511 *
512 * These BLESS real-time states can be used to synchronize
513 * an application with the BLESS or prevent radio interference with other
514 * peripherals, etc.
515 *
516 * BLE dual CPU mode requires an additional configuration IPC channel and IPC Interrupt
517 * structure to send notifications from the controller core to Host core.
518 * Refer to Cy_BLE_ConfigureIpcForInterruptCallback() for details.
519 *
520 * \note
521 * The user must call Cy_BLE_IntrNotifyIsrHandler() inside the user-defined BLESS
522 * interrupt service routine (ISR)
523 *
524 * \param intrMask
525 * All interrupts masks are specified in the #cy_en_ble_interrupt_callback_feature_t
526 * enumeration.
527 *
528 * \param CallBack
529 * The pointer to an application notify callback.
530 *
531 * \return
532 * \ref cy_en_ble_api_result_t : The return value indicates whether the function succeeded or
533 * failed. The possible error codes:
534 *
535 * Errors codes | Description
536 * ------------ | -----------
537 * CY_BLE_SUCCESS | The callback is registered successfully.
538 * CY_BLE_ERROR_INVALID_PARAMETER | Validation of the input parameters failed.
539 *
540 *******************************************************************************/
Cy_BLE_RegisterInterruptCallback(uint32_t intrMask,cy_ble_intr_callback_t CallBack)541 cy_en_ble_api_result_t Cy_BLE_RegisterInterruptCallback(uint32_t intrMask, cy_ble_intr_callback_t CallBack)
542 {
543 cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
544
545 if(CallBack != NULL)
546 {
547 /* Store the application callback and interrupt mask */
548 Cy_BLE_InterruptCallback = CallBack;
549 intrNotify.mask = intrMask;
550
551 /* Store pointer to intrNotify configuration */
552 intrNotifyPtr = &intrNotify;
553 }
554 else
555 {
556 apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
557 }
558 return apiResult;
559 }
560
561
562 /*******************************************************************************
563 * Function Name: Cy_BLE_ConfigureIpcForInterruptCallback
564 ****************************************************************************//**
565 *
566 * This function configures IPC channel for BLE interrupt notifications feature,
567 * when BLE is operating in BLE dual CPU mode.
568 *
569 * This function must be called only on the Host CPU core.
570 *
571 * \param ipcChan: IPC channel. Valid range: 9..15
572 * \param ipcIntr: IPC Interrupt structure. Valid range: 9..15
573 * \param ipcIntrPrior: IPC Interrupt priority. Valid range: 0..7
574 *
575 * \return
576 * \ref cy_en_ble_api_result_t : The return value indicates whether the function succeeded or
577 * failed. The possible error codes:
578 *
579 * Errors codes | Description
580 * ------------ | -----------
581 * CY_BLE_SUCCESS | The callback is registered successfully.
582 * CY_BLE_ERROR_INVALID_PARAMETER | Validation of the input parameters failed.
583 * CY_BLE_ERROR_INVALID_OPERATION | The IPC channel is busy (BLE dual CPU mode only).
584 *
585 *******************************************************************************/
Cy_BLE_ConfigureIpcForInterruptCallback(uint32_t ipcChan,uint32_t ipcIntr,uint32_t ipcIntrPrior)586 cy_en_ble_api_result_t Cy_BLE_ConfigureIpcForInterruptCallback(uint32_t ipcChan, uint32_t ipcIntr, uint32_t ipcIntrPrior)
587 {
588 /* Set up the IPC for BLE dual CPU mode */
589
590 cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
591
592 /* IPC channel 0...8 is reserved by system */
593 if( (ipcChan >= 9u) && (ipcChan <= 15u) && (ipcIntr >= 9u) && (ipcIntr <= 15u) &&
594 (ipcIntrPrior <= 7u) )
595 {
596 cy_en_ipc_pipe_status_t ipcStatus;
597 cy_stc_sysint_t intrConfig;
598 uint32_t rTimeout = 2000u; /* us */
599
600 /* Initialize the interrupt controller for CM4 and IPC Interrupt */
601 intrConfig.intrPriority = ipcIntrPrior;
602 intrConfig.intrSrc =(IRQn_Type) CY_IPC_INTR_NUM_TO_VECT((int32_t)ipcIntr);
603
604 (void)Cy_SysInt_Init(&intrConfig, &Cy_BLE_HAL_IntrNotifyIpcHandler);
605 NVIC_EnableIRQ(intrConfig.intrSrc);
606
607 /* Store IPC channel information in Interrupt Notify structure */
608 intrNotify.userIpcChan = (uint8_t) ipcChan;
609 intrNotify.userIpcIntr = (uint8_t) ipcIntr;
610 intrNotify.userIpcIntrPrior = (uint8_t) ipcIntrPrior;
611
612 /* Do not bring up an IPC release interrupt here; only set up a notify interrupt */
613 Cy_IPC_Drv_SetInterruptMask(Cy_IPC_Drv_GetIntrBaseAddr(ipcIntr),
614 CY_IPC_NO_NOTIFICATION, (1uL << ipcChan));
615
616 /*
617 * Send the address of the intrNotify structure to the controller core via CyPipe
618 * The IPC Pipe can be busy. If so, try sending a message after 2 ms.
619 */
620 do
621 {
622 ipcStatus = Cy_IPC_Pipe_SendMessage(CY_BLE_IPC_CONTROLLER_ADDR, CY_BLE_IPC_HOST_ADDR,
623 (void *)&intrNotify, NULL);
624 Cy_SysLib_DelayUs(1u);
625 rTimeout--;
626
627 }while((ipcStatus != CY_IPC_PIPE_SUCCESS) && (rTimeout != 0u));
628
629 if(ipcStatus != CY_IPC_PIPE_SUCCESS)
630 {
631 apiResult = CY_BLE_ERROR_INVALID_OPERATION;
632 }
633 }
634 else
635 {
636 apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
637 }
638
639 return(apiResult);
640 }
641
642
643 /*******************************************************************************
644 * Function Name: Cy_BLE_UnRegisterInterruptCallback
645 ****************************************************************************//**
646 *
647 * This function un-registers the callback that exposed BLE interrupt
648 * notifications to the application.
649 *
650 * \return
651 * \ref cy_en_ble_api_result_t : Return value indicates whether the function succeeded
652 * or failed. The following are possible error codes.
653 *
654 * Errors codes | Description
655 * ------------ | -----------
656 * CY_BLE_SUCCESS | The callback registered successfully.
657 * CY_BLE_ERROR_INVALID_OPERATION | The IPC channel is busy (BLE dual CPU mode only).
658 *
659 *******************************************************************************/
Cy_BLE_UnRegisterInterruptCallback(void)660 cy_en_ble_api_result_t Cy_BLE_UnRegisterInterruptCallback(void)
661 {
662 cy_en_ble_api_result_t apiResult;
663
664 /* Clean interrupt mask */
665 apiResult = Cy_BLE_RegisterInterruptCallback((uint32_t)CY_BLE_INTR_CALLBACK_NONE,
666 Cy_BLE_InterruptCallback);
667 if(apiResult == CY_BLE_SUCCESS)
668 {
669 /* Clean callback pointer */
670 Cy_BLE_InterruptCallback = NULL;
671 }
672
673 return(apiResult);
674 }
675
676
677 /*******************************************************************************
678 * Function Name: Cy_BLE_RegisterAppHostCallback
679 ****************************************************************************//**
680 *
681 * This function registers an application Host callback (BLE RTOS hook).
682 * The user can trigger an RTOS BLE task if the application Host callback was
683 * called.
684 *
685 * Theory of operation:
686 * The PSoC 6 BLE Middleware triggers this callback when the BLE Stack controller needs
687 * to process pending Stack events (by calling Cy_BLE_ProcessEvents()). This
688 * callback executes from within an ISR and must be very short.
689 *
690 * \note The application Host callback is called from the context of a high-
691 * priority ISR. Some RTOS (e.g. FreeRTOS) have restrictions on calling the RTOS
692 * functions from a high-priority ISR. The user application is responsible for
693 * integration of the BLE RTOS hook and RTOS functions and must ensure that RTOS
694 * allows calling RTOS API from BLE interrupt context.
695 * If direct call is forbidden, one of the possible solutions is to trig a
696 * low-priority interrupt from the application Host callback and then call the
697 * RTOS functions from a low-priority interrupt. For detail, refer to specific
698 * RTOS documentation.
699 *
700 * \param CallBack
701 * The pointer to the application Host callback.
702 *
703 * \return
704 * Error Codes | Description
705 * ------------ | -----------
706 * CY_BLE_SUCCESS | The callback registered successfully.
707 * CY_BLE_ERROR_INVALID_PARAMETER | On specifying NULL as the input parameter.
708 *
709 *******************************************************************************/
Cy_BLE_RegisterAppHostCallback(cy_ble_app_notify_callback_t CallBack)710 cy_en_ble_api_result_t Cy_BLE_RegisterAppHostCallback(cy_ble_app_notify_callback_t CallBack)
711 {
712 cy_en_ble_api_result_t apiResult = CY_BLE_SUCCESS;
713
714 if(CallBack != NULL)
715 {
716 Cy_BLE_HostRegisteredCallback = CallBack;
717 }
718 else
719 {
720 apiResult = CY_BLE_ERROR_INVALID_PARAMETER;
721 }
722 return apiResult;
723 }
724
725
726 /*******************************************************************************
727 * Function Name: Cy_BLE_UnRegisterAppHostCallback
728 ****************************************************************************//**
729 *
730 * This function un-registers an application Host callback (BLE RTOS hook).
731 *
732 *******************************************************************************/
Cy_BLE_UnRegisterAppHostCallback(void)733 void Cy_BLE_UnRegisterAppHostCallback(void)
734 {
735 Cy_BLE_HostRegisteredCallback = NULL;
736 }
737
738
739
740 /*******************************************************************************
741 *
742 * BLE LPM (Low Power mode)
743 *
744 *******************************************************************************/
745
746 /******************************************************************************
747 * Function Name: Cy_BLE_EnableSystemLowPowerMode
748 ***************************************************************************//**
749 *
750 * This function enables BLE low power mode (register BLE SysPm callback)
751 *
752 * This function must be used only in BLE single CPU mode.
753 *
754 ******************************************************************************/
Cy_BLE_EnableSystemLowPowerMode(void)755 void Cy_BLE_EnableSystemLowPowerMode(void)
756 {
757 /* Register BLE SysPm callback for CPU deep sleep */
758 Cy_BLE_RegisterPmCallbacksSingle();
759
760 Cy_BLE_RegisterPmCallbacksPtr = &Cy_BLE_RegisterPmCallbacksSingle;
761 Cy_BLE_UnregisterPmCallbacksPtr = &Cy_BLE_UnregisterHostPmCallbacksSingle;
762 }
763
764
765 /******************************************************************************
766 * Function Name: Cy_BLE_EnableHostLowPowerMode
767 ***************************************************************************//**
768 *
769 * This function enables BLE Low Power mode (register BLE SysPm callbacks)
770 *
771 * This function must be used only in BLE dual CPU mode and called on the CPU core
772 * where the BLE Host is running.
773 *
774 ******************************************************************************/
Cy_BLE_EnableHostLowPowerMode(void)775 void Cy_BLE_EnableHostLowPowerMode(void)
776 {
777 /* Register BLE SysPm callback for CPU deep sleep/sleep */
778 Cy_BLE_RegisterPmCallbacksDual();
779
780 Cy_BLE_RegisterPmCallbacksPtr = &Cy_BLE_RegisterPmCallbacksDual;
781 Cy_BLE_UnregisterPmCallbacksPtr = &Cy_BLE_UnregisterHostPmCallbacksDual;
782 }
783
784
785 /******************************************************************************
786 * Function Name: Cy_BLE_RegisterPmCallbacksSingle
787 ***************************************************************************//**
788 *
789 * Register BLE SysPm callback for CPU deep sleep
790 *
791 * This function is designated for internal usage.
792 *
793 ******************************************************************************/
Cy_BLE_RegisterPmCallbacksSingle(void)794 static void Cy_BLE_RegisterPmCallbacksSingle(void)
795 {
796 /* Register BLE SysPm callback for CPU deep sleep support */
797 bleDeepSleepCallback.callback = &Cy_BLE_DeepSleepCallbackSingleCore;
798 (void)Cy_SysPm_RegisterCallback(&bleDeepSleepCallback);
799 }
800
801
802 /******************************************************************************
803 * Function Name: Cy_BLE_RegisterPmCallbacksDual
804 ***************************************************************************//**
805 *
806 * Register BLE SysPm callback for CPU deep sleep/CPU sleep
807 *
808 * This function is designated for internal usage.
809 *
810 ******************************************************************************/
Cy_BLE_RegisterPmCallbacksDual(void)811 static void Cy_BLE_RegisterPmCallbacksDual(void)
812 {
813 /* Register BLE SysPm callback for CPU deep sleep support */
814 bleDeepSleepCallback.callback = &Cy_BLE_DeepSleepCallbackDualCore;
815 (void)Cy_SysPm_RegisterCallback(&bleDeepSleepCallback);
816
817 /* Register BLE SysPm callback for CPU sleep support, need only in
818 * BLE dual CPU mode for the Host core */
819 (void)Cy_SysPm_RegisterCallback(&bleSleepCallback);
820 }
821
822
823 /******************************************************************************
824 * Function Name: Cy_BLE_UnregisterHostPmCallbacksSingle
825 ***************************************************************************//**
826 *
827 * Unregister BLE SysPm callback for CPU deep sleep for Host core.
828 *
829 * This function is designated for internal usage.
830 *
831 ******************************************************************************/
Cy_BLE_UnregisterHostPmCallbacksSingle(void)832 static void Cy_BLE_UnregisterHostPmCallbacksSingle(void)
833 {
834 /* Unregister BLE SysPm callback for CPU deep sleep support */
835 (void)Cy_SysPm_UnregisterCallback(&bleDeepSleepCallback);
836 }
837
838
839 /******************************************************************************
840 * Function Name: Cy_BLE_UnregisterHostPmCallbacksDual
841 ***************************************************************************//**
842 *
843 * Unregister BLE SysPm callback for CPU deep sleep/CPU sleep for Host core.
844 *
845 * This function is designated for internal usage.
846 *
847 ******************************************************************************/
Cy_BLE_UnregisterHostPmCallbacksDual(void)848 static void Cy_BLE_UnregisterHostPmCallbacksDual(void)
849 {
850 /* Unregister BLE callback for CPU deep sleep support */
851 (void)Cy_SysPm_UnregisterCallback(&bleDeepSleepCallback);
852
853 /* Unregister sleep mode callback only in BLE dual CPU mode for the Host core */
854 /* Unregister BLE callback for CPU sleep support */
855 (void)Cy_SysPm_UnregisterCallback(&bleSleepCallback);
856 }
857
858
859 /*******************************************************************************
860 * Function Name: Cy_BLE_DeepSleepCallbackSingleCore
861 ****************************************************************************//**
862 *
863 * This function requests the BLE Stack to put Bluetooth Low Energy Sub-System
864 * (BLESS) to deep sleep mode for BLE single CPU mode.
865 *
866 * It is registered to the system power mode by Cy_SysPm_RegisterCallback()
867 * function with CY_SYSPM_DEEPSLEEP type. After registration, it is called by
868 * Cy_SysPm_DeepSleep() function prior entering the core into the CPU deep sleep
869 * power mode.
870 *
871 * When it is called with the enMode parameter set to CY_SYSPM_CHECK_READY,
872 * this function enters BLESS to CY_BLE_BLESS_DEEPSLEEP mode. It also checks the
873 * BLE Subsystem's current operational mode. When the
874 * Cy_BLE_StackGetBleSsState() function returns CY_BLE_BLESS_STATE_ECO_ON or
875 * CY_BLE_BLESS_STATE_DEEPSLEEP state, this function returns CY_SYSPM_PASS and
876 * allows putting the core into the CPU deep sleep power mode.
877 * At all other times, the function tries to send the core into CPU sleep mode.
878 *
879 * This function is available only when BLE Low Power mode is enabled (called
880 * Cy_BLE_EnableLPM).
881 *
882 * \param
883 * callbackParams Pointer to the structure with the syspm callback parameters.
884 *
885 * \param
886 * mode The associated syspm callback mode. See description of the
887 * cy_en_syspm_callback_mode_t type.
888 *
889 * \return
890 * * CY_SYSPM_SUCCESS - Entered and exited from BLESS deep sleep.
891 * * CY_SYSPM_FAIL - BLESS deep sleep not entered.
892 *
893 *******************************************************************************/
Cy_BLE_DeepSleepCallbackSingleCore(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)894 static cy_en_syspm_status_t Cy_BLE_DeepSleepCallbackSingleCore(cy_stc_syspm_callback_params_t *callbackParams,
895 cy_en_syspm_callback_mode_t mode)
896 {
897 /* Suppress unused variable warning */
898 (void) callbackParams;
899 (void) mode;
900
901 #if defined(COMPONENT_BLESS_HOST)
902 cy_en_syspm_status_t retVal;
903 static uint32_t interruptState = 0u;
904 cy_en_ble_bless_state_t blessState;
905
906 /* Local variable to store the status of BLESS Hardware block */
907 cy_en_ble_lp_mode_t sleepMode;
908
909 switch(mode)
910 {
911 case (CY_SYSPM_CHECK_READY):
912 if(Cy_BLE_GetState() == CY_BLE_STATE_INITIALIZING)
913 {
914 retVal = CY_SYSPM_FAIL;
915 }
916 else if(Cy_IPC_Sema_Status(CY_BLE_SEMA) == CY_IPC_SEMA_STATUS_LOCKED)
917 {
918 /* System do not enter CPU deep sleep if BLE Host start write operation */
919 retVal = CY_SYSPM_FAIL;
920 }
921 else if (Cy_BLE_HAL_IsEcoCpuClockSrc() == 1u)
922 {
923 /* System never enters CPU deep sleep if BLE ECO is CPU source */
924 retVal = CY_SYSPM_FAIL;
925 }
926 else
927 {
928 cy_en_ble_api_result_t retIsControllerActive;
929
930 /* Put BLESS into deep sleep and check the return status */
931 sleepMode = Cy_BLE_StackEnterLPM(CY_BLE_BLESS_DEEPSLEEP);
932
933 /* Disable global interrupt to prevent changes from any other interrupt ISR */
934 interruptState = Cy_SysLib_EnterCriticalSection();
935
936 /* Check the Status of BLESS */
937 blessState = Cy_BLE_StackGetBleSsState();
938
939 if(blessState == CY_BLE_BLESS_STATE_STOPPED)
940 {
941 retVal = CY_SYSPM_SUCCESS;
942 }
943 else if(sleepMode == CY_BLE_BLESS_DEEPSLEEP)
944 {
945 retIsControllerActive = Cy_BLE_MappingIsControllerActive(CY_BLE_CONTROLLER_SLEEP_MODE_DEEPSLEEP);
946
947 if(((blessState == CY_BLE_BLESS_STATE_ECO_ON) || (blessState == CY_BLE_BLESS_STATE_DEEPSLEEP))
948 && (retIsControllerActive == CY_BLE_SUCCESS))
949 {
950 /* Enter device CPU deep sleep */
951 retVal = CY_SYSPM_SUCCESS;
952 }
953 else
954 {
955 /* The BLESS hardware block cannot go to CPU deep sleep; try CPU sleep mode */
956 retVal = CY_SYSPM_FAIL;
957 }
958 }
959 else
960 {
961 retIsControllerActive = Cy_BLE_MappingIsControllerActive(CY_BLE_CONTROLLER_SLEEP_MODE_SLEEP);
962
963 if((blessState != CY_BLE_BLESS_STATE_EVENT_CLOSE) &&
964 (retIsControllerActive == CY_BLE_SUCCESS))
965 {
966 /* If the BLESS hardware block cannot go to CPU deep sleep and BLE event has not
967 * closed yet, then place CPU to sleep */
968 (void)Cy_SysPm_CpuEnterSleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
969 }
970 retVal = CY_SYSPM_FAIL;
971 }
972 if(retVal == CY_SYSPM_FAIL)
973 {
974 /* Enable interrupts after failing check */
975 Cy_SysLib_ExitCriticalSection(interruptState);
976 }
977 }
978 break;
979
980 /* Enable interrupts after wakeup */
981 case (CY_SYSPM_AFTER_TRANSITION):
982 Cy_SysLib_ExitCriticalSection(interruptState);
983 retVal = CY_SYSPM_SUCCESS;
984 break;
985
986 default:
987 retVal = CY_SYSPM_FAIL;
988 break;
989 }
990
991 return(retVal);
992 #else
993 return(CY_SYSPM_SUCCESS);
994 #endif /*defined(COMPONENT_BLESS_HOST) */
995 }
996
997
998 /*******************************************************************************
999 * Function Name: Cy_BLE_DeepSleepCallbackDualCore
1000 ****************************************************************************//**
1001 *
1002 * This function requests the BLE Stack to put Bluetooth Low Energy Sub-System
1003 * (BLESS) to CPU deep sleep mode for BLE dual CPU mode (Host).
1004 *
1005 * It is registered to the system power mode by Cy_SysPm_RegisterCallback()
1006 * function with CY_SYSPM_DEEPSLEEP type. After registration it is called by
1007 * Cy_SysPm_DeepSleep() function prior sending the core into the CPU deep sleep
1008 * power mode.
1009 *
1010 * When it is called with the enMode parameter set to CY_SYSPM_CHECK_READY,
1011 * the function enters BLESS to CY_BLE_BLESS_DEEPSLEEP mode. It also checks the
1012 * BLE Subsystem's current operational mode. When the
1013 * Cy_BLE_StackGetBleSsState() function returns CY_BLE_BLESS_STATE_ECO_ON or
1014 * CY_BLE_BLESS_STATE_DEEPSLEEP state, this function returns CY_SYSPM_PASS and
1015 * allows putting the core into the CPU deep sleep power mode.
1016 * At all other times, the function tries to send the core into sleep mode.
1017 *
1018 * This function is available only when BLE Low Power mode is enabled (called
1019 * Cy_BLE_EnableLPM).
1020 *
1021 * \param
1022 * callbackParams Pointer to the structure with the syspm callback parameters.
1023 *
1024 * \param
1025 * mode The associated syspm callback mode. See description of the
1026 * cy_en_syspm_callback_mode_t type.
1027 *
1028 * \return
1029 * * CY_SYSPM_SUCCESS - Entered and exited from BLESS deep sleep.
1030 * * CY_SYSPM_FAIL - BLESS deep sleep not entered.
1031 *
1032 *******************************************************************************/
Cy_BLE_DeepSleepCallbackDualCore(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)1033 static cy_en_syspm_status_t Cy_BLE_DeepSleepCallbackDualCore(cy_stc_syspm_callback_params_t *callbackParams,
1034 cy_en_syspm_callback_mode_t mode)
1035 {
1036 /* Suppress unused variable warning */
1037 (void) callbackParams;
1038 (void) mode;
1039
1040 #if defined(COMPONENT_BLESS_HOST_IPC)
1041 cy_en_syspm_status_t retVal;
1042 static uint32_t interruptState = 0u;
1043 cy_en_ble_bless_state_t blessState;
1044
1045 /* Local variable to store the status of BLESS Hardware block */
1046 cy_en_ble_lp_mode_t sleepMode;
1047
1048 switch(mode)
1049 {
1050 case (CY_SYSPM_CHECK_READY):
1051 if(Cy_BLE_GetState() == CY_BLE_STATE_INITIALIZING)
1052 {
1053 retVal = CY_SYSPM_FAIL;
1054 }
1055 else if(Cy_IPC_Sema_Status(CY_BLE_SEMA) == CY_IPC_SEMA_STATUS_LOCKED)
1056 {
1057 /* System do not enter CPU deep sleep if BLE Host start write operation */
1058 retVal = CY_SYSPM_FAIL;
1059 }
1060 else
1061 {
1062 /* Disable global interrupt to prevent changes from any other interrupt ISR */
1063 interruptState = Cy_SysLib_EnterCriticalSection();
1064
1065 /* Put BLESS into deep sleep and check the return status */
1066 sleepMode = Cy_BLE_StackEnterLPM(CY_BLE_BLESS_DEEPSLEEP);
1067
1068 /* Check the Status of BLESS */
1069 blessState = Cy_BLE_StackGetBleSsState();
1070
1071 if(sleepMode == CY_BLE_BLESS_DEEPSLEEP)
1072 {
1073
1074 if((blessState == CY_BLE_BLESS_STATE_ECO_ON) || (blessState == CY_BLE_BLESS_STATE_DEEPSLEEP))
1075
1076 {
1077 /* Enter device deep sleep */
1078 retVal = CY_SYSPM_SUCCESS;
1079 }
1080 else
1081 {
1082 /* The BLESS hardware block cannot go to CPU deep sleep; try CPU sleep mode */
1083 retVal = CY_SYSPM_FAIL;
1084 }
1085 }
1086 else
1087 {
1088 retVal = CY_SYSPM_FAIL;
1089 }
1090 if(retVal == CY_SYSPM_FAIL)
1091 {
1092 /* Enable interrupts after failing check */
1093 Cy_SysLib_ExitCriticalSection(interruptState);
1094 }
1095 }
1096 break;
1097
1098 /* Enable interrupts after wakeup */
1099 case (CY_SYSPM_AFTER_TRANSITION):
1100 Cy_SysLib_ExitCriticalSection(interruptState);
1101 retVal = CY_SYSPM_SUCCESS;
1102 break;
1103
1104 default:
1105 retVal = CY_SYSPM_FAIL;
1106 break;
1107 }
1108
1109 return(retVal);
1110 #else
1111 return(CY_SYSPM_SUCCESS);
1112 #endif /*defined(COMPONENT_BLESS_HOST_IPC) */
1113
1114 }
1115
1116
1117 /*******************************************************************************
1118 * Function Name: Cy_BLE_SleepCallbackDualCore
1119 ****************************************************************************//**
1120 *
1121 * This function requests the BLE Stack to put the Host to CPU sleep mode.
1122 *
1123 * It is registered to the system power mode by Cy_SysPm_RegisterCallback()
1124 * function with CY_SYSPM_SLEEP type. After registration, it is called by
1125 * Cy_SysPm_Sleep() function prior to sending the core into the CPU sleep
1126 * power mode.
1127 *
1128 * This function is available only when BLE Low Power mode is enabled (called
1129 * Cy_BLE_EnableLPM).
1130 *
1131 * \param
1132 * callbackParams Pointer to the structure with the syspm callback parameters.
1133 *
1134 * \param
1135 * mode The associated syspm callback mode. See description of the
1136 * cy_en_syspm_callback_mode_t type.
1137 *
1138 * \return
1139 * * CY_SYSPM_SUCCESS - Entered and exited from CPU sleep.
1140 * * CY_SYSPM_FAIL - CPU sleep not entered.
1141 *
1142 *******************************************************************************/
Cy_BLE_SleepCallbackDualCore(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)1143 static cy_en_syspm_status_t Cy_BLE_SleepCallbackDualCore(cy_stc_syspm_callback_params_t *callbackParams,
1144 cy_en_syspm_callback_mode_t mode)
1145 {
1146 /* Suppress unused variable warning */
1147 (void) callbackParams;
1148 (void) mode;
1149
1150 #if defined(COMPONENT_BLESS_HOST_IPC)
1151 cy_en_syspm_status_t retVal;
1152 static uint32_t interruptState = 0u;
1153
1154 /* Local variable to store the status of BLESS Hardware block */
1155 cy_en_ble_lp_mode_t sleepMode;
1156
1157 switch(mode)
1158 {
1159 case (CY_SYSPM_CHECK_READY):
1160 if(Cy_BLE_GetState() == CY_BLE_STATE_INITIALIZING)
1161 {
1162 retVal = CY_SYSPM_FAIL;
1163 }
1164 else
1165 {
1166 /* Disable global interrupt to prevent changes from any other interrupt ISR */
1167 interruptState = Cy_SysLib_EnterCriticalSection();
1168
1169 /* Put BLESS into deep sleep and check the return status */
1170 sleepMode = Cy_BLE_StackEnterLPM(CY_BLE_BLESS_DEEPSLEEP);
1171
1172 /* Check whether the Host is ready for CPU sleep mode */
1173 if(sleepMode != CY_BLE_BLESS_DEEPSLEEP)
1174 {
1175 retVal = CY_SYSPM_FAIL;
1176 /* Enable interrupts after failing check */
1177 Cy_SysLib_ExitCriticalSection(interruptState);
1178 }
1179 else
1180 {
1181 retVal = CY_SYSPM_SUCCESS;
1182 }
1183 }
1184 break;
1185
1186 /* Enable interrupts after wakeup */
1187 case (CY_SYSPM_AFTER_TRANSITION):
1188 Cy_SysLib_ExitCriticalSection(interruptState);
1189 retVal = CY_SYSPM_SUCCESS;
1190 break;
1191
1192 case (CY_SYSPM_CHECK_FAIL):
1193 Cy_SysLib_ExitCriticalSection(interruptState);
1194 retVal = CY_SYSPM_FAIL;
1195 break;
1196
1197 default:
1198 retVal = CY_SYSPM_FAIL;
1199 break;
1200 }
1201 return(retVal);
1202 #else
1203 return(CY_SYSPM_SUCCESS);
1204 #endif /*defined(COMPONENT_BLESS_HOST_IPC) */
1205 }
1206
1207 #endif /* CY_IP_MXBLESS */
1208
1209 /* [] END OF FILE */
1210