Beispiel #1
0
/*******************************************************************************
* Function Name: SimulateCyclingPower()
********************************************************************************
*
* Summary:
*   This function measures the die temperature and sends it to the client.
*
*******************************************************************************/
void SimulateCyclingPower(void)
{
    CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK;
    
    if(CyBle_GattGetBusyStatus() == CYBLE_STACK_STATE_FREE)
    {
        uint8 powerMeasureData[CYBLE_GATT_DEFAULT_MTU - 3];
        uint8 length = 0;
        
        /* Prepare data array */
        CyBle_Set16ByPtr(powerMeasureData, (CYBLE_CPS_CPM_TORQUE_PRESENT_BIT |
                                            CYBLE_CPS_CPM_TORQUE_SOURCE_BIT |
                                            CYBLE_CPS_CPM_WHEEL_BIT |
                                            CYBLE_CPS_CPM_ENERGY_BIT) & powerMeasure.flags);
        length += sizeof(powerMeasure.flags);
        CyBle_Set16ByPtr(powerMeasureData + length, powerMeasure.instantaneousPower);
        length += sizeof(powerMeasure.instantaneousPower);
        if((CYBLE_CPS_CPM_TORQUE_PRESENT_BIT & powerMeasure.flags) != 0u)
        {
            CyBle_Set16ByPtr(powerMeasureData + length, powerMeasure.accumulatedTorque);
            length += sizeof(uint16);
            CyBle_Set16ByPtr(powerMeasureData + length, (uint16)powerMeasure.cumulativeWheelRevolutions);
            CyBle_Set16ByPtr(powerMeasureData + length+2, (uint16)(powerMeasure.cumulativeWheelRevolutions >> 16u));
            length += sizeof(powerMeasure.cumulativeWheelRevolutions);
            CyBle_Set16ByPtr(powerMeasureData + length, powerMeasure.lastWheelEventTime);
            length += sizeof(powerMeasure.lastWheelEventTime);
        }
Beispiel #2
0
/*******************************************************************************
* Function Name: CpsCallBack()
********************************************************************************
*
* Summary:
*   This is an event callback function to receive service specific events from 
*   Cycling Power Service.
*
* Parameters:
*  event - the event code
*  *eventParam - the event parameters
*
* Return:
*  None.
*
*******************************************************************************/
void CpsCallback(uint32 event, void *eventParam)
{
    CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK;
    uint8 i;
    uint8 locCharIndex;
    locCharIndex = ((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->charIndex;
    DBG_PRINTF("CPS event: %lx, ", event);

    switch(event)
    {
        /* CPS Server - Notifications for Cycling Power Service Characteristic
        was enabled. The parameter of this event is a structure of
        CYBLE_CPS_CHAR_VALUE_T type.
        */
        case CYBLE_EVT_CPSS_NOTIFICATION_ENABLED:
            DBG_PRINTF("CYBLE_EVT_CPSS_NOTIFICATION_ENABLED: char: %x\r\n", locCharIndex);
            if(locCharIndex == CYBLE_CPS_POWER_MEASURE)
            {
                powerSimulation |= CPS_NOTIFICATION_MEASURE_ENABLE;
            }
            if(locCharIndex == CYBLE_CPS_POWER_VECTOR)
            {
                powerSimulation |= CPS_NOTIFICATION_VECTOR_ENABLE;
            }
            break;
        
        /* CPS Server - Notifications for Cycling Power Service Characteristic
            was disabled. The parameter of this event is a structure 
            of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSS_NOTIFICATION_DISABLED:
            DBG_PRINTF("CYBLE_EVT_CPSS_NOTIFICATION_DISABLED: char: %x\r\n", locCharIndex);
            if(locCharIndex == CYBLE_CPS_POWER_MEASURE)
            {
                powerSimulation &= ~CPS_NOTIFICATION_MEASURE_ENABLE;
            }
            if(locCharIndex == CYBLE_CPS_POWER_VECTOR)
            {
                powerSimulation &= ~CPS_NOTIFICATION_VECTOR_ENABLE;
            }
            break;
        
        /* CPS Server - Indication for Cycling Power Service Characteristic
            was enabled. The parameter of this event is a structure 
            of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSS_INDICATION_ENABLED:
            DBG_PRINTF("CYBLE_EVT_CPSS_INDICATION_ENABLED: char: %x\r\n", locCharIndex);
            powerSimulation |= CPS_INDICATION_ENABLE;
            break;
        
        /* CPS Server - Indication for Cycling Power Service Characteristic
            was disabled. The parameter of this event is a structure 
            of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSS_INDICATION_DISABLED:
            DBG_PRINTF("CYBLE_EVT_CPSS_INDICATION_DISABLED: char: %x\r\n", locCharIndex);
            powerSimulation &= ~CPS_INDICATION_ENABLE;
            break;
        
        /* CPS Server - Cycling Power Service Characteristic
            Indication was confirmed. The parameter of this event
            is a structure of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSS_INDICATION_CONFIRMED:
            DBG_PRINTF("CYBLE_EVT_CPSS_INDICATION_CONFIRMED: char: %x\r\n", locCharIndex);
            break;
        
        /* CPS Server - Broadcast for Cycling Power Service Characteristic
            was enabled. The parameter of this event
            is a structure of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSS_BROADCAST_ENABLED:
            DBG_PRINTF("CYBLE_EVT_CPSS_BROADCAST_ENABLED: char: %x\r\n", locCharIndex);
            powerSimulation |= CPS_BROADCAST_ENABLE;
            break;
        
        /* CPS Server - Broadcast for Cycling Power Service Characteristic
            was disabled. The parameter of this event
            is a structure of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSS_BROADCAST_DISABLED:
            DBG_PRINTF("CYBLE_EVT_CPSS_BROADCAST_DISABLED: char: %x\r\n", locCharIndex);
            powerSimulation &= ~CPS_BROADCAST_ENABLE;
            CyBle_CpssStopBroadcast();
            DBG_PRINTF("Stop Broadcast \r\n");
            break;
        
        /* CPS Server - Write Request for Cycling Power Service Characteristic 
            was received. The parameter of this event is a structure
            of CYBLE_CPS_CHAR_VALUE_T type.
        */
        case CYBLE_EVT_CPSS_CHAR_WRITE:
            DBG_PRINTF("CYBLE_EVT_CPSS_CHAR_WRITE: %x ", locCharIndex);
            ShowValue(((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value);
            if(locCharIndex == CYBLE_CPS_POWER_CP)
            {
                uint8 cpOpCode;
                cpOpCode = ((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[0];
                /* Prepare general response */
                powerCPResponse = 1u;
                powerCPData[CYBLE_CPS_CP_RESP_LENGTH] = 3u; /* Length of response */
                powerCPData[CYBLE_CPS_CP_RESP_OP_CODES] = CYBLE_CPS_CP_OC_RC;
                powerCPData[CYBLE_CPS_CP_RESP_REQUEST_OP_CODE] = cpOpCode;
                powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_SUCCESS;
            
                DBG_PRINTF("CP Opcode %x: ", cpOpCode);
                switch(cpOpCode)
                {
                    case CYBLE_CPS_CP_OC_SCV:
                        DBG_PRINTF("Set Cumulative Value \r\n");
                        /* Initiate the procedure to set a cumulative value. The new value is sent as parameter 
                           following op code (parameter defined per service). The response to this control point is 
                           Op Code 0x20 followed by the appropriate Response Value. */
                        if(((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->len == (sizeof(uint32) + 1u))
                        {
                            powerMeasure.cumulativeWheelRevolutions = *(uint32 *)&((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1];
                        }
                        else
                        {
                            powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_INVALID_PARAMETER;                            
                        }
                        break;
                    case CYBLE_CPS_CP_OC_USL:      
                        DBG_PRINTF("Update Sensor Location \r\n");
                        /* Update to the location of the Sensor with the value sent as parameter to this op code. 
                           The response to this control point is Op Code 0x20 followed by the appropriate Response 
                           Value. */
                        if(((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1] < CYBLE_CPS_SL_COUNT)
                        {
                            apiResult = CyBle_CpssSetCharacteristicValue(CYBLE_CPS_SENSOR_LOCATION, sizeof(uint8), &((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1]);
                        }
                        else
                        {
                            powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_INVALID_PARAMETER;                            
                        }
                        (void)apiResult;
                        DBG_PRINTF("CyBle_CpssSetCharacteristicValue SENSOR_LOCATION, API result: %x \r\n", apiResult);
                        break;
                    case CYBLE_CPS_CP_OC_RSSL: 
                        DBG_PRINTF("Request Supported Sensor Locations \r\n");
                        /* Request a list of supported locations where the Sensor can be attached. The response to this
                           control point is Op Code 0x20 followed by the appropriate Response Value, including a list
                           of supported Sensor locations in the Response Parameter. */
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += CYBLE_CPS_SL_COUNT; /* Length of response */
                        for(i = 0; i < CYBLE_CPS_SL_COUNT; i++)
                        {
                            powerCPData[CYBLE_CPS_CP_RESP_PARAMETER + i] = i;
                        }
                        
                        break;
                    case CYBLE_CPS_CP_OC_SCRL: 
                        DBG_PRINTF("Set Crank Length \r\n");
                        /* Initiate the procedure to set the crank length value to Sensor. The new value is sent as a 
                           parameter with preceding Op Code 0x04 operand. The response to this control point is Op Code
                           0x20 followed by the appropriate Response Value. */
                        if(((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->len == (sizeof(uint16) + 1u))
                        {
                            cyBle_cpssAdjustment.crankLength =  *(uint16 *)&((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1];
                        }
                        else
                        {
                            powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_INVALID_PARAMETER;                            
                        }
                        break;
                    case CYBLE_CPS_CP_OC_RCRL:
                        DBG_PRINTF(" Request Crank Length \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += sizeof(cyBle_cpssAdjustment.crankLength); /* Length of response */
                        CyBle_Set16ByPtr(powerCPData + CYBLE_CPS_CP_RESP_PARAMETER, cyBle_cpssAdjustment.crankLength);
                        break;
                    case CYBLE_CPS_CP_OC_SCHL:
                        DBG_PRINTF("Set Chain Length \r\n");
                        if(((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->len == (sizeof(uint16) + 1u))
                        {
                            cyBle_cpssAdjustment.chainLength =  *(uint16 *)&((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1];
                        }
                        else
                        {
                            powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_INVALID_PARAMETER;                            
                        }
                        break;
                    case CYBLE_CPS_CP_OC_RCHL:
                        DBG_PRINTF("Request Chain Length \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += sizeof(cyBle_cpssAdjustment.chainLength); /* Length of response */
                        CyBle_Set16ByPtr(powerCPData + CYBLE_CPS_CP_RESP_PARAMETER, cyBle_cpssAdjustment.chainLength);
                        break;
                    case CYBLE_CPS_CP_OC_SCHW:
                        DBG_PRINTF("Set Chain Weight \r\n");
                        if(((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->len == (sizeof(uint16) + 1u))
                        {
                            cyBle_cpssAdjustment.chainWeight =  *(uint16 *)&((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1];
                        }
                        else
                        {
                            powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_INVALID_PARAMETER;                            
                        }
                        break;
                    case CYBLE_CPS_CP_OC_RCHW:
                        DBG_PRINTF("Request Chain Weight \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += sizeof(cyBle_cpssAdjustment.chainWeight); /* Length of response */
                        CyBle_Set16ByPtr(powerCPData + CYBLE_CPS_CP_RESP_PARAMETER, cyBle_cpssAdjustment.chainWeight);
                        break;
                    case CYBLE_CPS_CP_OC_SSL:
                        DBG_PRINTF("Set Span Length \r\n");
                        if(((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->len == (sizeof(uint16) + 1u))
                        {
                            cyBle_cpssAdjustment.spanLength =  *(uint16 *)&((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1];
                        }
                        else
                        {
                            powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_INVALID_PARAMETER;                            
                        }
                        break;
                    case CYBLE_CPS_CP_OC_RSL:
                        DBG_PRINTF(" Request Span Length \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += sizeof(cyBle_cpssAdjustment.spanLength); /* Length of response */
                        CyBle_Set16ByPtr(powerCPData + CYBLE_CPS_CP_RESP_PARAMETER, cyBle_cpssAdjustment.spanLength);
                        break;
                    case CYBLE_CPS_CP_OC_SOC:
                        DBG_PRINTF("Start Offset Compensation \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += sizeof(cyBle_cpssAdjustment.offsetCompensation); /* Length of response */
                        CyBle_Set16ByPtr(powerCPData + CYBLE_CPS_CP_RESP_PARAMETER, cyBle_cpssAdjustment.offsetCompensation);
                        break;
                    case CYBLE_CPS_CP_OC_MCPMCC:
                        DBG_PRINTF("Mask Cycling Power Measurement Characteristic Content \r\n");
                        { 
                            uint16 mask = *(uint16 *)&((CYBLE_CPS_CHAR_VALUE_T *)eventParam)->value->val[1];
                            if((mask & CYBLE_CPS_CP_ENERGY_RESERVED) != 0u)
                            {
                                powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_INVALID_PARAMETER;                            
                            }

                            if((mask & CYBLE_CPS_CP_PEDAL_PRESENT_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_PEDAL_PRESENT_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_TORQUE_PRESENT_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_TORQUE_PRESENT_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_WHEEL_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_WHEEL_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_CRANK_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_CRANK_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_MAGNITUDES_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_FORCE_MAGNITUDES_BIT;
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_TORQUE_MAGNITUDES_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_ANGLES_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_ANGLES_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_TOP_DEAD_SPOT_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_TOP_DEAD_SPOT_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_BOTTOM_DEAD_SPOT_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_BOTTOM_DEAD_SPOT_BIT;
                            }
                            if((mask & CYBLE_CPS_CP_ENERGY_BIT) != 0u) 
                            {
                                powerMeasure.flags &= ~CYBLE_CPS_CPM_ENERGY_BIT;
                            }
                        }
                        break;
                    case CYBLE_CPS_CP_OC_RSR: 
                        DBG_PRINTF("Request Sampling Rate \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += sizeof(cyBle_cpssAdjustment.samplingRate); /* Length of response */
                        powerCPData[CYBLE_CPS_CP_RESP_PARAMETER] = cyBle_cpssAdjustment.samplingRate;
                        break;
                    case CYBLE_CPS_CP_OC_RFCD:
                        DBG_PRINTF("Request Factory Calibration Date \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_LENGTH] += sizeof(cyBle_cpssAdjustment.factoryCalibrationDate); /* Length of response */
                        memcpy(powerCPData + CYBLE_CPS_CP_RESP_PARAMETER, &cyBle_cpssAdjustment.factoryCalibrationDate, 
                               sizeof(cyBle_cpssAdjustment.factoryCalibrationDate));
                        break;
                    case CYBLE_CPS_CP_OC_RC:
                        DBG_PRINTF("Response Code \r\n");
                        break;
                    default:
                        DBG_PRINTF("Op Code Not supported \r\n");
                        powerCPData[CYBLE_CPS_CP_RESP_VALUE] = CYBLE_CPS_CP_RC_NOT_SUPPORTED;
                        break;
                }
            }
            break;
        
        /* CPS Client - Cycling Power Service Characteristic
            Notification was received. The parameter of this event
            is a structure of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSC_NOTIFICATION:
            break;
        
        /* CPS Client - Cycling Power Service Characteristic
            Indication was received. The parameter of this event
            is a structure of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSC_INDICATION:
            break;
        
        /* CPS Client - Read Response for Read Request of Cycling Power Service
            Characteristic value. The parameter of this event
            is a structure of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSC_READ_CHAR_RESPONSE:
            break;

        /* CPS Client - Write Response for Write Request of Cycling Power Service
            Characteristic value. The parameter of this event
            is a structure of CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSC_WRITE_CHAR_RESPONSE:
            break;
        
        /* CPS Client - Read Response for Read Request of Cycling Power
            Service Characteristic Descriptor Read request. The 
            parameter of this event is a structure of
            CYBLE_CPS_DESCR_VALUE_T type
        */
        case CYBLE_EVT_CPSC_READ_DESCR_RESPONSE:
            break;
        
        /* CPS Client - Write Response for Write Request of Cycling Power
            Service Characteristic Configuration Descriptor value.
            The parameter of this event is a structure of 
            CYBLE_CPS_DESCR_VALUE_T type
        */
        case CYBLE_EVT_CPSC_WRITE_DESCR_RESPONSE:
            break;

        /* CPS Client - This event is triggered every time a device receive
            non-connectable undirected advertising event.
            The parameter of this event is a structure of 
            CYBLE_CPS_CHAR_VALUE_T type
        */
        case CYBLE_EVT_CPSC_SCAN_PROGRESS_RESULT:
            break;
            
		default:
            DBG_PRINTF("Not supported event\r\n");
			break;
    }
}
Beispiel #3
0
/*******************************************************************************
* Function Name: HrssSendHeartRateNtf
********************************************************************************
*
* Summary:
*  Packs the Heart Rate Measurement characteristic structure into the
*  uint8 array prior to sending it to the collector. Also clears the
*  CYBLE_HRS_HRM_HRVAL16, CYBLE_HRS_HRM_ENEXP and CYBLE_HRS_HRM_RRINT flags.
*
* Parameters:
*  attHandle:  Pointer to the handle which consists of device ID and ATT
*              connection ID.
*
* Return:
*  CYBLE_API_RESULT_T: API result will state if API succeeded
*                      (CYBLE_ERROR_OK)
*                      or failed with error codes.
*
*******************************************************************************/
void HrssSendHeartRateNtf()
{
    uint8 pdu[CYBLE_HRS_HRM_CHAR_LEN];
    uint8 nextPtr;
    uint8 length;
    uint8 rrInt;

    /* Flags field is always the first byte */
    pdu[0u] = hrsHeartRate.flags & (uint8) ~CYBLE_HRS_HRM_HRVAL16;

    /* If the Heart Rate value exceeds one byte */
    if(hrsHeartRate.heartRateValue > 0x00FFu)
    {
        /* then set the CYBLE_HRS_HRM_HRVAL16 flag */
        pdu[0u] |= CYBLE_HRS_HRM_HRVAL16;
        /* and set the full 2-bytes Heart Rate value */
        CyBle_Set16ByPtr(&pdu[1u], hrsHeartRate.heartRateValue);
        /* The next data will be located beginning from 3rd byte */
        nextPtr = 3u;
    }
    else
    {
        /* Else leave the CYBLE_HRS_HRM_HRVAL16 flag remains being cleared */
        /* and set only LSB of the  Heart Rate value */
        pdu[1u] = (uint8) hrsHeartRate.heartRateValue;
        /* The next data will be located beginning from 2nd byte */
        nextPtr = 2u;
    }

    /* If the Energy Expended flag is set */
    if(0u != (hrsHeartRate.flags & CYBLE_HRS_HRM_ENEXP))
    {
        /* clear the CYBLE_HRS_HRM_ENEXP flag */
        hrsHeartRate.flags &= (uint8) ~CYBLE_HRS_HRM_ENEXP;
        /* and set the 2-bytes Energy Expended value */
        CyBle_Set16ByPtr(&pdu[nextPtr], hrsHeartRate.energyExpendedValue);
        /* add 2 bytes: Energy Expended value is uint16 */
        nextPtr += 2u;
    }

    if(HrssAreThereRrIntervals())
    {
        /* Calculate the actual length of pdu: the RR-interval block length should be an even number */
        length = ((CYBLE_HRS_HRM_CHAR_LEN - nextPtr) & ~0x01) + nextPtr;

        rrInt = hrssRrIntPtr;

        while(nextPtr < length)
        {
            /* Increment the rrInterval array pointer in RR-Interval buffer size loop */
            rrInt++;
            if(rrInt >= CYBLE_HRS_HRM_RRSIZE)
            {
                rrInt = 0;
            }

            if(hrsHeartRate.rrInterval[rrInt] != 0)
            {
                /* Copy the non-zero RR-Interval into the pdu */
                CyBle_Set16ByPtr(&pdu[nextPtr], hrsHeartRate.rrInterval[rrInt]);
                /* Clear the current RR-Interval in the buffer */
                hrsHeartRate.rrInterval[rrInt] = 0;
                /* Add 2 bytes: RR-Interval value is uint16 */
                nextPtr += 2u;
            }

            if(rrInt == hrssRrIntPtr)
            {
                hrsHeartRate.flags &= (uint8) ~CYBLE_HRS_HRM_RRINT;
                break;
            }
        }

        hrssRrIntCnt = 0;
    }
	
	apiResult = CyBle_HrssSendNotification(cyBle_connHandle, CYBLE_HRS_HRM, nextPtr, pdu);
    
    if(apiResult != CYBLE_ERROR_OK)
    {
        printf("HrssSendHeartRateNtf API Error: %x \r\n", apiResult);
    }
    else
    {
        printf("Heart Rate Notification is sent successfully, Heart Rate = %d \r\n", hrsHeartRate.heartRateValue);
    }
    
    /* Store heart rate data */
    DataLogging(nextPtr, pdu);
}