/******************************************************************************* * Function Name: LowPowerImplementation() ******************************************************************************** * Summary: * Implements low power in the project. * * Parameters: * None * * Return: * None * * Theory: * The function tries to enter deep sleep as much as possible - whenever the * BLE is idle and the UART transmission/reception is not happening. At all other * times, the function tries to enter CPU sleep. * *******************************************************************************/ static void LowPowerImplementation(void) { CYBLE_LP_MODE_T bleMode; uint8 interruptStatus; /* For advertising and connected states, implement deep sleep * functionality to achieve low power in the system. For more details * on the low power implementation, refer to the Low Power Application * Note. */ if((CyBle_GetState() == CYBLE_STATE_ADVERTISING) || (CyBle_GetState() == CYBLE_STATE_CONNECTED)) { bleMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); interruptStatus = CyEnterCriticalSection(); if(bleMode == CYBLE_BLESS_DEEPSLEEP) { if((CyBle_GetBleSsState() == CYBLE_BLESS_STATE_ECO_ON) || (CyBle_GetBleSsState() == CYBLE_BLESS_STATE_DEEPSLEEP)) { /* Deep sleep only if UART completes transfer and we * are not waiting for the user to enter anything. */ if(((UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0u) && (ancsUsageState != ANCS_USAGE_INCOMING_CALL_WAITING_FOR_INPUT)) { CySysPmDeepSleep(); } else { CySysPmSleep(); } } } else { if(CyBle_GetBleSsState() != CYBLE_BLESS_STATE_EVENT_CLOSE) { CySysPmSleep(); } } CyExitCriticalSection(interruptStatus); } }
/******************************************************************************* * Function Name: AppCallBack ******************************************************************************** * * Summary: * Call back function for BLE stack to handle BLESS events * * Parameters: * event - the event generated by stack * eventParam - the parameters related to the corresponding event * * Return: * None. * *******************************************************************************/ void AppCallBack(uint32 event, void *eventParam) { CYBLE_GATTC_READ_BY_TYPE_RSP_PARAM_T *readResponse; CYBLE_GAPC_ADV_REPORT_T *advReport; CYBLE_GATTC_FIND_BY_TYPE_RSP_PARAM_T *findResponse; CYBLE_GATTC_FIND_INFO_RSP_PARAM_T *findInfoResponse; switch (event) { case CYBLE_EVT_STACK_ON: break; case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT: advReport = (CYBLE_GAPC_ADV_REPORT_T *) eventParam; /* check if report has manfacturing data corresponding to the intended matching peer */ if((advReport->eventType == CYBLE_GAPC_SCAN_RSP) && (advReport->dataLen == 0x06) \ && (advReport->data[1] == 0xff) && (advReport->data[2] == 0x31) \ && (advReport->data[3] == 0x01) && (advReport->data[4] == 0x3b) \ && (advReport->data[5] == 0x04)) { peerDeviceFound = true; memcpy(peerAddr.bdAddr, advReport->peerBdAddr, sizeof(peerAddr.bdAddr)); peerAddr.type = advReport->peerAddrType; #ifdef PRINT_MESSAGE_LOG UART_UartPutString("\n\r\n\rServer with matching custom service discovered..."); #endif } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* RESET all flags */ peerDeviceFound = false; notificationEnabled = false; infoExchangeState = INFO_EXCHANGE_START; #ifdef PRINT_MESSAGE_LOG UART_UartPutString("\n\r DISCONNECTED!!! \n\r "); while(0 != (UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID)); #endif /* RESET Uart and flush all buffers */ UART_Stop(); UART_SpiUartClearTxBuffer(); UART_SpiUartClearRxBuffer(); UART_Start(); break; case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP: readResponse = (CYBLE_GATTC_READ_BY_TYPE_RSP_PARAM_T *) eventParam; if(0 == memcmp((uint8 *)&(readResponse->attrData.attrValue[5]), (uint8 *)uartTxAttrUuid, 16)) { txCharHandle = readResponse->attrData.attrValue[3]; txCharHandle |= (readResponse->attrData.attrValue[4] << 8); infoExchangeState |= TX_ATTR_HANDLE_FOUND; } else if(0 == memcmp((uint8 *)&(readResponse->attrData.attrValue[5]), (uint8 *)uartRxAttrUuid, 16)) { rxCharHandle = readResponse->attrData.attrValue[3]; rxCharHandle |= (readResponse->attrData.attrValue[4] << 8); infoExchangeState |= RX_ATTR_HANDLE_FOUND; } break; case CYBLE_EVT_GATTC_FIND_INFO_RSP: findInfoResponse = (CYBLE_GATTC_FIND_INFO_RSP_PARAM_T *) eventParam; if((0x29 == findInfoResponse->handleValueList.list[3]) && \ (0x02 == findInfoResponse->handleValueList.list[2])) { txCharDescHandle = findInfoResponse->handleValueList.list[0]; txCharDescHandle |= findInfoResponse->handleValueList.list[1] << 8; infoExchangeState |= TX_CCCD_HANDLE_FOUND; } break; case CYBLE_EVT_GATTC_XCHNG_MTU_RSP: /*set the 'mtuSize' variable based on the minimum MTU supported by both devices */ if(CYBLE_GATT_MTU > ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu) { mtuSize = ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu; } else { mtuSize = CYBLE_GATT_MTU; } infoExchangeState |= MTU_XCHNG_COMPLETE; break; case CYBLE_EVT_GATTC_HANDLE_VALUE_NTF: HandleUartRxTraffic((CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T *)eventParam); break; case CYBLE_EVT_GATTC_FIND_BY_TYPE_VALUE_RSP: findResponse = (CYBLE_GATTC_FIND_BY_TYPE_RSP_PARAM_T *) eventParam; bleUartServiceHandle = findResponse->range->startHandle; bleUartServiceEndHandle = findResponse->range->endHandle; infoExchangeState |= BLE_UART_SERVICE_HANDLE_FOUND; break; case CYBLE_EVT_GATTS_XCNHG_MTU_REQ: /*set the 'mtuSize' variable based on the minimum MTU supported by both devices */ if(CYBLE_GATT_MTU > ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu) { mtuSize = ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu; } else { mtuSize = CYBLE_GATT_MTU; } break; case CYBLE_EVT_GATTC_WRITE_RSP: notificationEnabled = true; #ifdef PRINT_MESSAGE_LOG UART_UartPutString("\n\rNotifications enabled\n\r"); UART_UartPutString("\n\rStart entering data:\n\r"); #endif break; case CYBLE_EVT_GATT_CONNECT_IND: #ifdef PRINT_MESSAGE_LOG UART_UartPutString("\n\rConnection established"); #endif break; default: break; } }
int main() { #ifdef LOW_POWER_MODE CYBLE_LP_MODE_T lpMode; CYBLE_BLESS_STATE_T blessState; #endif CYBLE_API_RESULT_T bleApiResult; CyGlobalIntEnable; /* Start UART and BLE component and display project information */ UART_Start(); bleApiResult = CyBle_Start(AppCallBack); if(bleApiResult == CYBLE_ERROR_OK) { #ifdef PRINT_MESSAGE_LOG UART_UartPutString("\n\r************************************************************"); UART_UartPutString("\n\r***************** BLE UART example project *****************"); UART_UartPutString("\n\r************************************************************\n\r"); UART_UartPutString("\n\rDevice role \t: CENTRAL"); #ifdef LOW_POWER_MODE UART_UartPutString("\n\rLow Power Mode \t: ENABLED"); #else UART_UartPutString("\n\rLow Power Mode \t: DISABLED"); #endif #ifdef FLOW_CONTROL UART_UartPutString("\n\rFlow Control \t: ENABLED"); #else UART_UartPutString("\n\rFlow Control \t: DISABLED"); #endif #endif } else { #ifdef PRINT_MESSAGE_LOG UART_UartPutString("\n\r\t\tCyBle stack initilization FAILED!!! \n\r "); #endif /* Enter infinite loop */ while(1); } CyBle_ProcessEvents(); /*************************************************************************** * Main polling loop ***************************************************************************/ while(1) { #ifdef LOW_POWER_MODE if((CyBle_GetState() != CYBLE_STATE_INITIALIZING) && (CyBle_GetState() != CYBLE_STATE_DISCONNECTED)) { /* Enter DeepSleep mode between connection intervals */ lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); CyGlobalIntDisable; blessState = CyBle_GetBleSsState(); if(lpMode == CYBLE_BLESS_DEEPSLEEP) { if((blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) && \ (UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0u) { #ifdef FLOW_CONTROL EnableUartRxInt(); #endif CySysPmSleep(); #ifdef FLOW_CONTROL DisableUartRxInt(); #endif } } else { if((blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) && \ (UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0u) { #ifdef FLOW_CONTROL EnableUartRxInt(); #endif CySysPmSleep(); #ifdef FLOW_CONTROL DisableUartRxInt(); #endif } } CyGlobalIntEnable; /* Handle advertising led blinking */ HandleLeds(); } #else HandleLeds(); #endif /******************************************************************* * Process all pending BLE events in the stack *******************************************************************/ HandleBleProcessing(); CyBle_ProcessEvents(); } }
int main() { /* Variable declarations */ CYBLE_LP_MODE_T lpMode; CYBLE_BLESS_STATE_T blessState; uint8 InterruptsStatus; /* Start communication component */ UART_Start(); /* Enable global interrupts */ CyGlobalIntEnable; /* Internal low power oscillator is stopped as it is not used in this project */ CySysClkIloStop(); /* Set the divider for ECO, ECO will be used as source when IMO is switched off to save power, ** to drive the HFCLK */ CySysClkWriteEcoDiv(CY_SYS_CLK_ECO_DIV8); CyBle_Start(StackEventHandler); /*Infinite Loop*/ for(;;) { if((UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0) { if(CyBle_GetState() != CYBLE_STATE_INITIALIZING) { /* Put BLE sub system in DeepSleep mode when it is idle */ lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); /* Disable global interrupts to avoid any other tasks from interrupting this section of code*/ InterruptsStatus = CyEnterCriticalSection(); /* Get current state of BLE sub system to check if it has successfully entered deep sleep state */ blessState = CyBle_GetBleSsState(); /* If BLE sub system has entered deep sleep, put chip into deep sleep for reducing power consumption */ if(lpMode == CYBLE_BLESS_DEEPSLEEP) { if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) { /* Put the chip into the deep sleep state as there are no pending tasks and BLE has also ** successfully entered BLE DEEP SLEEP mode */ CySysPmDeepSleep(); } } /* BLE sub system has not entered deep sleep, wait for completion of radio operations */ else if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) { /* change HF clock source from IMO to ECO, as IMO can be stopped to save power */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_ECO); /* stop IMO for reducing power consumption */ CySysClkImoStop(); /* put the CPU to sleep */ CySysPmSleep(); /* starts execution after waking up, start IMO */ CySysClkImoStart(); /* change HF clock source back to IMO */ CySysClkWriteHfclkDirect(CY_SYS_CLK_HFCLK_IMO); } /*Enable interrupts */ CyExitCriticalSection(InterruptsStatus); }/*end of if(CyBle_GetState() != CYBLE_STATE_INITIALIZING)*/ CyBle_ProcessEvents(); } } }
/******************************************************************************* * Function Name: main ******************************************************************************** * * Summary: * Main function. * * Parameters: * None * * Return: * None * *******************************************************************************/ int main() { CYBLE_LP_MODE_T lpMode; CYBLE_BLESS_STATE_T blessState; CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK; CyGlobalIntEnable; /* ADD_CODE_TO - Start the BLE component and register StackEventHandler function */ apiResult = CyBle_Start(StackEventHandler); if(apiResult != CYBLE_ERROR_OK) { /* BLE stack initialization failed, check your configuration */ CYASSERT(0); } /* Register LLS event handler function */ CyBle_LlsRegisterAttrCallback(LlsEventHandler); while(1) { /* Process all the pending BLE tasks. This single API call will service all * the BLE stack events. This API MUST be called at least once per BLE connection interval */ CyBle_ProcessEvents(); if(CyBle_GetState() != CYBLE_STATE_INITIALIZING) /* Waiting for BLE component initialization */ { static uint8 blinkTimeout = BLINK_TIMEOUT; /* Update link loss alert LED status based on IAS Alert level characteristic */ if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED || (CyBle_GetState() == CYBLE_STATE_CONNECTED && CyBle_GetRssi() > RSSI_THRESHOLD)) { switch(linkAlertLevel) { case NO_ALERT: Link_Alert_LED_Write(LED_OFF); break; case MILD_ALERT: if(--blinkTimeout == 0) { Link_Alert_LED_Write(Link_Alert_LED_Read() ^ 0x01); blinkTimeout = BLINK_TIMEOUT; } break; case HIGH_ALERT: Link_Alert_LED_Write(LED_ON); break; } } else { Link_Alert_LED_Write(LED_OFF); } } lpMode = CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP); CyGlobalIntDisable; blessState = CyBle_GetBleSsState(); if(lpMode == CYBLE_BLESS_DEEPSLEEP) { if(blessState == CYBLE_BLESS_STATE_ECO_ON || blessState == CYBLE_BLESS_STATE_DEEPSLEEP) { /* Put the device into the Deep Sleep mode only when all debug information has been sent */ if((UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0u) { CySysPmDeepSleep(); } else { CySysPmSleep(); } } } else { if(blessState != CYBLE_BLESS_STATE_EVENT_CLOSE) { CySysPmSleep(); } } CyGlobalIntEnable; if((cyBle_pendingFlashWrite != 0u) && ((UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) == 0u)) { apiResult = CyBle_StoreBondingData(0u); printf("Store bonding data, status: %x \r\n", apiResult); } } }
/******************************************************************************* * Function Name: main() ******************************************************************************** * Summary: * Main function for the project. * * Parameters: * None * * Return: * None * * Theory: * The function starts BLE and UART components. * This function process all BLE events and also implements the low power * functionality - both deep sleep and hibernate. * *******************************************************************************/ int main() { CYBLE_GAP_BONDED_DEV_ADDR_LIST_T bondedDeviceList; /* Enable global interrupts */ CyGlobalIntEnable; /* Start a new UART session and clear screen */ UART_Start(); UART_UartPutChar(12); UART_UartPutString("=====ANCS Demo=====\n\r"); UART_UartPutString("\n\rPress 'R' at any time to clear the bonded device list. \n\r"); /* Initialize BLE component and ANCS related information */ CyBle_Start(StackEventHandler); Ancs_Reset(); /* Check whether we already have anything in the bonded device list */ CyBle_GapGetBondedDevicesList(&bondedDeviceList); if(bondedDeviceList.count != 0) { authState = AUTHENTICATION_BONDING_COMPLETE; } /* Custom service discovery is not implemented in the component yet. * So we need to enable all the events to come to the application * in order to process raw data for ANCS service discovery. */ cyBle_eventHandlerFlag |= CYBLE_ENABLE_ALL_EVENTS; /* Inifinite loop */ for(;;) { /* Process all the generated events. This includes the general events * for BLE initialization, advertisement, connection etc. It also * includes the events for service discovery and ANCS notifications. */ CyBle_ProcessEvents(); /* Handle the state machine for ANCS notifications */ Ancs_StateMachine(); /* Handle bonding of device information*/ BondingImplementation(); /* To achieve low power in the device */ LowPowerImplementation(); /* Enter hibernate mode when necessary. */ if(enterHibernateFlag == true) { WakeupPin_ClearInterrupt(); WakeupPinInterrupt_Start(); /* Wait for the UART to complete transfer */ while((UART_SpiUartGetTxBufferSize() + UART_GET_TX_FIFO_SR_VALID) != 0u); CySysPmHibernate(); } } }