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