initial commit
This commit is contained in:
ambiq-hal-sys/ambiq-sparkfun-sdk/third_party/exactle/ble-profiles/sources/profiles/plxps/plxps_api.h
Vendored
+185
@@ -0,0 +1,185 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Pulse Oximeter profile sensor.
|
||||
*
|
||||
* Copyright (c) 2012-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef PLXPS_API_H
|
||||
#define PLXPS_API_H
|
||||
|
||||
#include "app_hw.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! \addtogroup PULSE_OXIMETER_PROFILE
|
||||
* \{ */
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Configurable parameters */
|
||||
typedef struct
|
||||
{
|
||||
wsfTimerTicks_t period; /*!< \brief Continuous Measurement timer expiration period in ms */
|
||||
} plxpsCfg_t;
|
||||
|
||||
/*! \brief Pulse Oximeter continuous measurement structure */
|
||||
typedef appPlxCm_t plxpCm_t;
|
||||
|
||||
/*! \brief Pulse Oximeter spot check measurement structure */
|
||||
typedef appPlxScm_t plxpScm_t;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize the Pulse Oximeter profile sensor.
|
||||
*
|
||||
* \param handlerId DM connection identifier.
|
||||
* \param pCfg Configuration parameters.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsInit(wsfHandlerId_t handlerId, plxpsCfg_t *pCfg);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief This function is called by the application when a message that requires
|
||||
* processing by the pulse oximeter profile sensor is received.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsProcMsg(wsfMsgHdr_t *pMsg);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle a button press.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param btn Button press.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsBtn(dmConnId_t connId, uint8_t btn);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief ATTS write callback for pulse oximeter service.
|
||||
*
|
||||
* \param connId DM connection identifier.
|
||||
* \param handle ATT handle.
|
||||
* \param operation ATT operation.
|
||||
* \param offset Write offset.
|
||||
* \param len Write length.
|
||||
* \param pValue Value to write.
|
||||
* \param pAttr Attribute to write.
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t PlxpsWriteCback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set the supported features of the pulse oximeter sensor.
|
||||
*
|
||||
* \param feature Feature bitmask.
|
||||
* \param measStatus Measurement status.
|
||||
* \param sensorStatus Sensor status.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsSetFeature(uint16_t feature, uint16_t measStatus, uint32_t sensorStatus);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set the CCCD index used by the application for pulse oximeter service characteristics.
|
||||
*
|
||||
* \param plxscCccIdx Pulse Oximeter spot check CCCD index.
|
||||
* \param plxcCccIdx Pulse Oximeter continuous CCCD index.
|
||||
* \param racpCccIdx Record access control point CCCD index.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsSetCccIdx(uint8_t plxscCccIdx, uint8_t plxcCccIdx, uint8_t racpCccIdx);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Start periodic pulse oximeter measurement. This function starts a timer to perform
|
||||
* periodic measurements.
|
||||
*
|
||||
* \param connId DM connection identifier.
|
||||
* \param timerEvt WSF event designated by the application for the timer.
|
||||
* \param plxmCccIdx Index of pulse oximeter CCC descriptor in CCC descriptor handle table.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsMeasStart(dmConnId_t connId, uint8_t timerEvt, uint8_t plxmCccIdx);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Stop periodic pulse oximeter measurement.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsMeasStop(void);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a spot check measurement indication.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param pMeas Pointer to pulse oximeter spot check measurement.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsSendSpotCheckMeas(dmConnId_t connId, plxpScm_t *pMeas);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a Continuous measurement notification.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param pMeas Pointer to Pulse Oximiter continuous measurement.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsSendContinuousMeas(dmConnId_t connId, plxpCm_t *pMeas);
|
||||
|
||||
/*! \} */ /* PULSE_OXIMETER_PROFILE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* PLXPS_API_H */
|
||||
Vendored
+261
@@ -0,0 +1,261 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Pulse Oximeter profile example record database and access functions.
|
||||
*
|
||||
* Copyright (c) 2012-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "util/bstream.h"
|
||||
#include "att_api.h"
|
||||
#include "svc_ch.h"
|
||||
#include "svc_gls.h"
|
||||
#include "app_api.h"
|
||||
#include "plxps_api.h"
|
||||
#include "plxps_main.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! Number of records in example database */
|
||||
#define PLXPS_DB_NUM_RECORDS 3
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! Control block */
|
||||
static struct
|
||||
{
|
||||
uint8_t numRec;
|
||||
} plxpsDbCb;
|
||||
|
||||
/*! Example record database */
|
||||
static const plxpsRec_t plxpsDb[PLXPS_DB_NUM_RECORDS] =
|
||||
{
|
||||
/* record 1 */
|
||||
{
|
||||
/* spotCheck */
|
||||
{
|
||||
0, /* Flags */
|
||||
SFLT_TO_UINT16(96, 1), /* Pulse Oximeter Spo2 (SFLOAT) */
|
||||
SFLT_TO_UINT16(60, 1), /* Pulse Oximeter Pulse (SFLOAT) */
|
||||
{2012, 6, 15, 20, 52, 36}, /* timestamp */
|
||||
0, /* Measurement status */
|
||||
0, /* Sensor status */
|
||||
SFLT_TO_UINT16(96, 1), /* Pulse Amplitude Index */
|
||||
}
|
||||
},
|
||||
|
||||
/* record 2 */
|
||||
{
|
||||
/* spotCheck */
|
||||
{
|
||||
0, /* Flags */
|
||||
SFLT_TO_UINT16(96, 1), /* Pulse Oximeter Spo2 (SFLOAT) */
|
||||
SFLT_TO_UINT16(60, 1), /* Pulse Oximeter Pulse (SFLOAT) */
|
||||
{2012, 6, 15, 20, 52, 36}, /* timestamp */
|
||||
0, /* Measurement status */
|
||||
0, /* Sensor status */
|
||||
SFLT_TO_UINT16(96, 1), /* Pulse Amplitude Index */
|
||||
}
|
||||
},
|
||||
/* record 3 */
|
||||
{
|
||||
/* spotCheck */
|
||||
{
|
||||
0, /* Flags */
|
||||
SFLT_TO_UINT16(96, 1), /* Pulse Oximeter Spo2 (SFLOAT) */
|
||||
SFLT_TO_UINT16(60, 1), /* Pulse Oximeter Pulse (SFLOAT) */
|
||||
{2012, 6, 15, 20, 52, 36}, /* timestamp */
|
||||
0, /* Measurement status */
|
||||
0, /* Sensor status */
|
||||
SFLT_TO_UINT16(96, 1), /* Pulse Amplitude Index */
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the next database record after the given current record.
|
||||
*
|
||||
* \param pCurrRec Pointer to current record.
|
||||
*
|
||||
* \return Pointer to record or NULL if no record.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static const plxpsRec_t *plxpsDbGetEnd()
|
||||
{
|
||||
return plxpsDb + plxpsDbCb.numRec;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the next database record after the given current record.
|
||||
*
|
||||
* \param pCurrRec Pointer to current record.
|
||||
*
|
||||
* \return Pointer to record or NULL if no record.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static plxpsRec_t *plxpsDbGetNext(plxpsRec_t *pCurrRec)
|
||||
{
|
||||
if (plxpsDbCb.numRec == 0 || pCurrRec == plxpsDbGetEnd())
|
||||
{
|
||||
plxpsDbCb.numRec = 0;
|
||||
return NULL;
|
||||
}
|
||||
else if (pCurrRec == NULL)
|
||||
{
|
||||
return (plxpsRec_t *) plxpsDb;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (pCurrRec + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the next record filtered for "all".
|
||||
*
|
||||
* \param pCurrRec Pointer to current record.
|
||||
* \param pRec Return pointer to next record, if found.
|
||||
*
|
||||
* \return CH_RACP_RSP_SUCCESS if a record is found, otherwise an error status is returned.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t plxpsDbOpAll(plxpsRec_t *pCurrRec, plxpsRec_t **pRec)
|
||||
{
|
||||
*pRec = plxpsDbGetNext(pCurrRec);
|
||||
return (*pRec != NULL) ? CH_RACP_RSP_SUCCESS : CH_RACP_RSP_NO_RECORDS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize the pulse oximeter record database.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsDbInit(void)
|
||||
{
|
||||
plxpsDbCb.numRec = PLXPS_DB_NUM_RECORDS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the next record that matches the given filter parameters that follows
|
||||
* the given current record.
|
||||
*
|
||||
* \param oper Operator.
|
||||
* \param pCurrRec Pointer to current record.
|
||||
* \param pRec Return pointer to next record, if found.
|
||||
*
|
||||
* \return CH_RACP_RSP_SUCCESS if a record is found, otherwise an error status is returned.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t plxpsDbGetNextRecord(uint8_t oper, plxpsRec_t *pCurrRec, plxpsRec_t **pRec)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
if (oper == CH_RACP_OPERATOR_ALL)
|
||||
{
|
||||
status = plxpsDbOpAll(pCurrRec, pRec);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = CH_RACP_RSP_INV_OPERATOR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Delete records that match the given filter parameters.
|
||||
*
|
||||
* \param oper Operator.
|
||||
*
|
||||
* \return CH_RACP_RSP_SUCCESS if records deleted, otherwise an error status is returned.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t plxpsDbDeleteRecords(uint8_t oper)
|
||||
{
|
||||
/* only 'all records' is supported */
|
||||
if (oper == CH_RACP_OPERATOR_ALL)
|
||||
{
|
||||
plxpsDbCb.numRec = 0;
|
||||
|
||||
return CH_RACP_RSP_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CH_RACP_RSP_INV_OPERATOR;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the number of records matching the filter parameters.
|
||||
*
|
||||
* \param oper Operator.
|
||||
* \param pNumRec Returns number of records which match filter parameters.
|
||||
|
||||
*
|
||||
* \return RACP status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t plxpsDbGetNumRecords(uint8_t oper, uint8_t *pNumRec)
|
||||
{
|
||||
plxpsRec_t *pCurrRec = NULL;
|
||||
uint8_t status;
|
||||
|
||||
*pNumRec = 0;
|
||||
while ((status = plxpsDbGetNextRecord(oper, pCurrRec, &pCurrRec)) == CH_RACP_RSP_SUCCESS)
|
||||
{
|
||||
(*pNumRec)++;
|
||||
}
|
||||
|
||||
if (status == CH_RACP_RSP_NO_RECORDS)
|
||||
{
|
||||
status = CH_RACP_RSP_SUCCESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Generate a new record.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsDbGenerateRecord(void)
|
||||
{
|
||||
if (plxpsDbCb.numRec < PLXPS_DB_NUM_RECORDS)
|
||||
{
|
||||
plxpsDbCb.numRec++;
|
||||
}
|
||||
}
|
||||
+785
@@ -0,0 +1,785 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Pulse Oximeter profile sensor.
|
||||
*
|
||||
* Copyright (c) 2012-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "wsf_types.h"
|
||||
#include "wsf_assert.h"
|
||||
#include "wsf_trace.h"
|
||||
#include "util/bstream.h"
|
||||
#include "att_api.h"
|
||||
#include "svc_ch.h"
|
||||
#include "svc_plxs.h"
|
||||
#include "app_api.h"
|
||||
#include "app_ui.h"
|
||||
#include "plxps_api.h"
|
||||
#include "plxps_main.h"
|
||||
|
||||
/**************************************************************************************************
|
||||
Local Variables
|
||||
**************************************************************************************************/
|
||||
|
||||
/* Control block */
|
||||
static struct
|
||||
{
|
||||
wsfTimer_t measTimer; /* continuous measurement timer */
|
||||
plxpsCfg_t *pCfg; /* configurable parameters */
|
||||
plxpsRec_t *pCurrRec; /* Pointer to current measurement record */
|
||||
plxpCm_t plxpsCm; /* Continuous measurement data */
|
||||
bool_t inProgress; /* TRUE if RACP procedure in progress */
|
||||
bool_t cmTxPending; /* TRUE if Continuous Measurement tx pending */
|
||||
bool_t txReady; /* TRUE if ready to send next notification or indication */
|
||||
bool_t aborting; /* TRUE if abort procedure in progress */
|
||||
uint8_t plxscCccIdx; /* Pulse Oximeter spot check measurement CCCD index */
|
||||
uint8_t plxcCccIdx; /* Pulse Oximeter continuous measurement CCCD index */
|
||||
uint8_t racpCccIdx; /* Record access control point CCCD index */
|
||||
} plxpsCb;
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Build a spot check measurement characteristic.
|
||||
*
|
||||
* \param pBuf Pointer to buffer to hold the built characteristic.
|
||||
* \param pScm Pulse Oximeter spot check measurement values.
|
||||
*
|
||||
* \return Length of pBuf in bytes.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t plxpsBuildScm(uint8_t *pBuf, plxpScm_t *pScm)
|
||||
{
|
||||
uint8_t *p = pBuf;
|
||||
uint8_t flags = pScm->flags;
|
||||
|
||||
/* flags */
|
||||
UINT8_TO_BSTREAM(p, flags);
|
||||
|
||||
/* Manditory SpO2 */
|
||||
UINT16_TO_BSTREAM(p, pScm->spo2);
|
||||
|
||||
/* Manditory Pulse Rate */
|
||||
UINT16_TO_BSTREAM(p, pScm->pulseRate);
|
||||
|
||||
/* Timestamp */
|
||||
if (flags & CH_PLXSC_FLAG_TIMESTAMP)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, pScm->timestamp.year);
|
||||
UINT8_TO_BSTREAM(p, pScm->timestamp.month);
|
||||
UINT8_TO_BSTREAM(p, pScm->timestamp.day);
|
||||
UINT8_TO_BSTREAM(p, pScm->timestamp.hour);
|
||||
UINT8_TO_BSTREAM(p, pScm->timestamp.min);
|
||||
UINT8_TO_BSTREAM(p, pScm->timestamp.sec);
|
||||
}
|
||||
|
||||
/* Measurement Status */
|
||||
if (flags & CH_PLXSC_FLAG_MEASUREMENT_STATUS)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, pScm->measStatus);
|
||||
}
|
||||
|
||||
/* Device and Sensor Status */
|
||||
if (flags & CH_PLXSC_FLAG_SENSOR_STATUS)
|
||||
{
|
||||
UINT24_TO_BSTREAM(p, pScm->sensorStatus);
|
||||
}
|
||||
|
||||
/* Pulse Amplitude Index */
|
||||
if (flags & CH_PLXSC_FLAG_PULSE_AMP_INDX)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, pScm->pulseAmpIndex);
|
||||
}
|
||||
|
||||
/* return length */
|
||||
return (uint8_t) (p - pBuf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Build a Continuous measurement characteristic.
|
||||
*
|
||||
* \param pBuf Pointer to buffer to hold the built characteristic.
|
||||
* \param pCm Pulse Oximeter continuous measurement values.
|
||||
*
|
||||
* \return Length of pBuf in bytes.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static uint8_t plxpsBuildCm(uint8_t *pBuf, plxpCm_t *pCm)
|
||||
{
|
||||
uint8_t *p = pBuf;
|
||||
uint8_t flags = pCm->flags;
|
||||
|
||||
/* flags */
|
||||
UINT8_TO_BSTREAM(p, flags);
|
||||
|
||||
/* Manditory SpO2 */
|
||||
UINT16_TO_BSTREAM(p, pCm->spo2);
|
||||
|
||||
/* Manditory Pulse Rate */
|
||||
UINT16_TO_BSTREAM(p, pCm->pulseRate);
|
||||
|
||||
/* SpO2PR Fast */
|
||||
if (flags & CH_PLXC_FLAG_SPO2PR_FAST)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, pCm->spo2Fast);
|
||||
UINT16_TO_BSTREAM(p, pCm->pulseRateFast);
|
||||
}
|
||||
|
||||
/* SpO2PR Slow */
|
||||
if (flags & CH_PLXC_FLAG_SPO2PR_SLOW)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, pCm->spo2Slow);
|
||||
UINT16_TO_BSTREAM(p, pCm->pulseRateSlow);
|
||||
}
|
||||
|
||||
/* Measurement Status */
|
||||
if (flags & CH_PLXC_FLAG_MEASUREMENT_STATUS)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, pCm->measStatus);
|
||||
}
|
||||
|
||||
/* Device and Sensor Status */
|
||||
if (flags & CH_PLXC_FLAG_SENSOR_STATUS)
|
||||
{
|
||||
UINT24_TO_BSTREAM(p, pCm->sensorStatus);
|
||||
}
|
||||
|
||||
/* Pulse Amplitude Index */
|
||||
if (flags & CH_PLXC_FLAG_PULSE_AMP_INDX)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, pCm->pulseAmpIndex);
|
||||
}
|
||||
|
||||
|
||||
/* return length */
|
||||
return (uint8_t) (p - pBuf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a Continuous measurement notification.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param pMeas Pointer to Pulse Oximiter continuous measurement.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsSendContinuousMeas(dmConnId_t connId, plxpCm_t *pMeas)
|
||||
{
|
||||
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN];
|
||||
uint8_t len;
|
||||
|
||||
/* build continuous measurement characteristic */
|
||||
len = plxpsBuildCm(buf, pMeas);
|
||||
|
||||
/* send notification */
|
||||
AttsHandleValueNtf(connId, PLXS_CONTINUOUS_HDL, len, buf);
|
||||
plxpsCb.txReady = FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a spot check measurement indication.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param pMeas Pointer to pulse oximeter spot check measurement.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsSendSpotCheckMeas(dmConnId_t connId, plxpScm_t *pMeas)
|
||||
{
|
||||
uint8_t buf[ATT_DEFAULT_PAYLOAD_LEN];
|
||||
uint8_t len;
|
||||
|
||||
/* build spot check measurement characteristic */
|
||||
len = plxpsBuildScm(buf, pMeas);
|
||||
|
||||
/* send indication */
|
||||
AttsHandleValueInd(connId, PLXS_SPOT_CHECK_HDL, len, buf);
|
||||
plxpsCb.txReady = FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a RACP response indication.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param opcode RACP opcode.
|
||||
* \param status RACP status.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsRacpSendRsp(dmConnId_t connId, uint8_t opcode, uint8_t status)
|
||||
{
|
||||
uint8_t buf[PLXPS_RACP_RSP_LEN];
|
||||
|
||||
/* build response */
|
||||
buf[0] = CH_RACP_OPCODE_RSP;
|
||||
buf[1] = CH_RACP_OPERATOR_NULL;
|
||||
buf[2] = opcode;
|
||||
buf[3] = status;
|
||||
|
||||
/* send indication */
|
||||
AttsHandleValueInd(connId, PLXS_RECORD_ACCESS_HDL, PLXPS_RACP_RSP_LEN, buf);
|
||||
plxpsCb.txReady = FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Send a RACP number of records response indication.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param numRec Number of records.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsRacpSendNumRecRsp(dmConnId_t connId, uint16_t numRec)
|
||||
{
|
||||
uint8_t buf[PLXPS_RACP_NUM_REC_RSP_LEN];
|
||||
|
||||
/* build response */
|
||||
buf[0] = CH_RACP_OPCODE_NUM_RSP;
|
||||
buf[1] = CH_RACP_OPERATOR_NULL;
|
||||
buf[2] = UINT16_TO_BYTE0(numRec);
|
||||
buf[3] = UINT16_TO_BYTE1(numRec);
|
||||
|
||||
/* send indication */
|
||||
AttsHandleValueInd(connId, PLXS_RECORD_ACCESS_HDL, PLXPS_RACP_RSP_LEN, buf);
|
||||
plxpsCb.txReady = FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle connection open.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void plxpsConnOpen(dmEvt_t *pMsg)
|
||||
{
|
||||
/* initialize */
|
||||
plxpsCb.pCurrRec = NULL;
|
||||
plxpsCb.aborting = FALSE;
|
||||
plxpsCb.inProgress = FALSE;
|
||||
plxpsCb.txReady = FALSE;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle connection close.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void plxpsConnClose(dmEvt_t *pMsg)
|
||||
{
|
||||
plxpsCb.pCurrRec = NULL;
|
||||
plxpsCb.aborting = FALSE;
|
||||
|
||||
PlxpsMeasStop();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle an ATT handle value confirm.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void plxpsHandleValueCnf(attEvt_t *pMsg)
|
||||
{
|
||||
dmConnId_t connId = (dmConnId_t) pMsg->hdr.param;
|
||||
plxpsCb.txReady = TRUE;
|
||||
|
||||
/* send continuous measurement if necessary */
|
||||
if (plxpsCb.cmTxPending == TRUE)
|
||||
{
|
||||
plxpsSendContinuousMeas((dmConnId_t) plxpsCb.measTimer.msg.param, &plxpsCb.plxpsCm);
|
||||
plxpsCb.txReady = FALSE;
|
||||
plxpsCb.cmTxPending = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* if aborting finish that up */
|
||||
if (plxpsCb.aborting)
|
||||
{
|
||||
plxpsCb.aborting = FALSE;
|
||||
plxpsRacpSendRsp(connId, CH_RACP_OPCODE_ABORT, CH_RACP_RSP_SUCCESS);
|
||||
}
|
||||
|
||||
/* if this is for RACP indication */
|
||||
if (pMsg->handle == PLXS_RECORD_ACCESS_HDL)
|
||||
{
|
||||
/* procedure no longer in progress */
|
||||
plxpsCb.inProgress = FALSE;
|
||||
}
|
||||
/* if this is for measurement or continuous notification */
|
||||
else if (pMsg->handle == PLXS_SPOT_CHECK_HDL || pMsg->handle == PLXS_CONTINUOUS_HDL)
|
||||
{
|
||||
if (plxpsCb.pCurrRec != NULL)
|
||||
{
|
||||
/* if there is another record */
|
||||
if (plxpsDbGetNextRecord(CH_RACP_OPERATOR_ALL, plxpsCb.pCurrRec, &plxpsCb.pCurrRec) == CH_RACP_RSP_SUCCESS)
|
||||
{
|
||||
/* send measurement */
|
||||
plxpsSendSpotCheckMeas(connId, (plxpScm_t*) plxpsCb.pCurrRec);
|
||||
}
|
||||
/* else all records sent; send RACP response */
|
||||
else
|
||||
{
|
||||
plxpsRacpSendRsp(connId, CH_RACP_OPCODE_REPORT, CH_RACP_RSP_SUCCESS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle a RACP report stored records operation.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param oper Operator.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void plxpsRacpReport(dmConnId_t connId, uint8_t oper)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
/* if record found */
|
||||
if ((status = plxpsDbGetNextRecord(oper, NULL, &plxpsCb.pCurrRec)) == CH_RACP_RSP_SUCCESS)
|
||||
{
|
||||
/* send spot check measurement */
|
||||
plxpsSendSpotCheckMeas(connId, (plxpScm_t *) plxpsCb.pCurrRec);
|
||||
}
|
||||
/* if not successful send response */
|
||||
else
|
||||
{
|
||||
plxpsRacpSendRsp(connId, CH_RACP_OPCODE_REPORT, status);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle a RACP delete records operation.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param oper Operator.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void plxpsRacpDelete(dmConnId_t connId, uint8_t oper)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
/* delete records */
|
||||
status = plxpsDbDeleteRecords(oper);
|
||||
|
||||
/* send response */
|
||||
plxpsRacpSendRsp(connId, CH_RACP_OPCODE_DELETE, status);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle a RACP abort operation.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void plxpsRacpAbort(dmConnId_t connId)
|
||||
{
|
||||
/* if operation in progress */
|
||||
if (plxpsCb.inProgress)
|
||||
{
|
||||
/* abort operation and clean up */
|
||||
plxpsCb.pCurrRec = NULL;
|
||||
}
|
||||
|
||||
/* send response */
|
||||
if (plxpsCb.txReady)
|
||||
{
|
||||
plxpsRacpSendRsp(connId, CH_RACP_OPCODE_ABORT, CH_RACP_RSP_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
plxpsCb.aborting = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle a RACP report number of stored records operation.
|
||||
*
|
||||
* \param connId Connection ID.
|
||||
* \param oper Operator.
|
||||
* \param pOperand Operand data.
|
||||
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
static void plxpsRacpReportNum(dmConnId_t connId, uint8_t oper)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t numRec;
|
||||
|
||||
/* get number of records */
|
||||
status = plxpsDbGetNumRecords(oper, &numRec);
|
||||
|
||||
if (status == CH_RACP_RSP_SUCCESS)
|
||||
{
|
||||
/* send response */
|
||||
plxpsRacpSendNumRecRsp(connId, numRec);
|
||||
}
|
||||
else
|
||||
{
|
||||
plxpsRacpSendRsp(connId, CH_RACP_OPCODE_REPORT_NUM, status);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize the Pulse Oximeter profile sensor.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsInit(wsfHandlerId_t handlerId, plxpsCfg_t *pCfg)
|
||||
{
|
||||
plxpsCb.measTimer.handlerId = handlerId;
|
||||
plxpsCb.pCfg = pCfg;
|
||||
plxpsDbInit();
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief This function is called by the application when the periodic measurement
|
||||
* timer expires.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsMeasTimerExp(wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
/* read pulse oximeter measurement data */
|
||||
AppHwPlxcmRead(&plxpsCb.plxpsCm);
|
||||
|
||||
plxpsCb.cmTxPending = TRUE;
|
||||
|
||||
/* if ready to send measurements */
|
||||
if (plxpsCb.txReady)
|
||||
{
|
||||
plxpsSendContinuousMeas((dmConnId_t) plxpsCb.measTimer.msg.param, &plxpsCb.plxpsCm);
|
||||
plxpsCb.txReady = FALSE;
|
||||
plxpsCb.cmTxPending = FALSE;
|
||||
}
|
||||
|
||||
/* restart timer */
|
||||
WsfTimerStartMs(&plxpsCb.measTimer, plxpsCb.pCfg->period);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief This function is called by the application when a message that requires
|
||||
* processing by the pulse oximeter profile sensor is received.
|
||||
*
|
||||
* \param pMsg Event message.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsProcMsg(wsfMsgHdr_t *pMsg)
|
||||
{
|
||||
if (pMsg->event == plxpsCb.measTimer.msg.event)
|
||||
{
|
||||
plxpsMeasTimerExp(pMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(pMsg->event)
|
||||
{
|
||||
case DM_CONN_OPEN_IND:
|
||||
plxpsConnOpen((dmEvt_t *) pMsg);
|
||||
break;
|
||||
|
||||
case DM_CONN_CLOSE_IND:
|
||||
plxpsConnClose((dmEvt_t *) pMsg);
|
||||
break;
|
||||
|
||||
case ATTS_HANDLE_VALUE_CNF:
|
||||
plxpsHandleValueCnf((attEvt_t *) pMsg);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Handle a button press.
|
||||
*
|
||||
* \param connId Connection identifier.
|
||||
* \param btn Button press.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsBtn(dmConnId_t connId, uint8_t btn)
|
||||
{
|
||||
/* button actions when connected */
|
||||
if (connId != DM_CONN_ID_NONE)
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case APP_UI_BTN_2_LONG:
|
||||
/* generate a new record */
|
||||
plxpsDbGenerateRecord();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* button actions when not connected */
|
||||
else
|
||||
{
|
||||
switch (btn)
|
||||
{
|
||||
case APP_UI_BTN_2_LONG:
|
||||
/* generate a new record */
|
||||
plxpsDbGenerateRecord();
|
||||
break;
|
||||
|
||||
case APP_UI_BTN_2_EX_LONG:
|
||||
/* delete all records */
|
||||
plxpsDbDeleteRecords(CH_RACP_OPERATOR_ALL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief ATTS write callback for pulse oximeter service record access control point. Use this
|
||||
* function as a parameter to SvcPlxCbackRegister().
|
||||
*
|
||||
* \return ATT status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t PlxpsWriteCback(dmConnId_t connId, uint16_t handle, uint8_t operation,
|
||||
uint16_t offset, uint16_t len, uint8_t *pValue, attsAttr_t *pAttr)
|
||||
{
|
||||
uint8_t opcode;
|
||||
uint8_t oprator;
|
||||
|
||||
/* sanity check on length */
|
||||
if (len < PLXPS_RACP_MIN_WRITE_LEN)
|
||||
{
|
||||
return ATT_ERR_LENGTH;
|
||||
}
|
||||
|
||||
/* if control point not configured for indication */
|
||||
if (!AttsCccEnabled(connId, plxpsCb.racpCccIdx))
|
||||
{
|
||||
return ATT_ERR_CCCD;
|
||||
}
|
||||
|
||||
/* parse opcode and operator and adjust remaining parameter length */
|
||||
BSTREAM_TO_UINT8(opcode, pValue);
|
||||
BSTREAM_TO_UINT8(oprator, pValue);
|
||||
len -= 2;
|
||||
|
||||
/* handle a procedure in progress */
|
||||
if (opcode != CH_RACP_OPCODE_ABORT && plxpsCb.inProgress)
|
||||
{
|
||||
return ATT_ERR_IN_PROGRESS;
|
||||
}
|
||||
|
||||
/* handle record request when notifications not enabled */
|
||||
if (opcode == CH_RACP_OPCODE_REPORT && !AttsCccEnabled(connId, plxpsCb.plxscCccIdx))
|
||||
{
|
||||
return ATT_ERR_CCCD;
|
||||
}
|
||||
|
||||
/* verify opcode */
|
||||
if (opcode < CH_RACP_OPCODE_REPORT || opcode > CH_RACP_OPCODE_RSP)
|
||||
{
|
||||
plxpsRacpSendRsp(connId, opcode, CH_RACP_RSP_OPCODE_NOT_SUP);
|
||||
}
|
||||
|
||||
/* verify operator */
|
||||
if ((opcode != CH_RACP_OPCODE_ABORT && oprator != CH_RACP_OPERATOR_ALL) ||
|
||||
(opcode == CH_RACP_OPCODE_ABORT && oprator != CH_RACP_OPERATOR_NULL))
|
||||
{
|
||||
if (oprator > CH_RACP_OPERATOR_LAST)
|
||||
plxpsRacpSendRsp(connId, opcode, CH_RACP_RSP_OPERATOR_NOT_SUP);
|
||||
else
|
||||
plxpsRacpSendRsp(connId, opcode, CH_RACP_RSP_INV_OPERATOR);
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/* verify operands */
|
||||
if (len > 0)
|
||||
{
|
||||
plxpsRacpSendRsp(connId, opcode, CH_RACP_RSP_INV_OPERAND);
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
switch (opcode)
|
||||
{
|
||||
/* report records */
|
||||
case CH_RACP_OPCODE_REPORT:
|
||||
plxpsRacpReport(connId, oprator);
|
||||
break;
|
||||
|
||||
/* delete records */
|
||||
case CH_RACP_OPCODE_DELETE:
|
||||
plxpsRacpDelete(connId, oprator);
|
||||
break;
|
||||
|
||||
/* abort current operation */
|
||||
case CH_RACP_OPCODE_ABORT:
|
||||
plxpsRacpAbort(connId);
|
||||
break;
|
||||
|
||||
/* report number of records */
|
||||
case CH_RACP_OPCODE_REPORT_NUM:
|
||||
plxpsRacpReportNum(connId, oprator);
|
||||
break;
|
||||
|
||||
/* unsupported opcode */
|
||||
default:
|
||||
plxpsRacpSendRsp(connId, opcode, CH_RACP_RSP_OPCODE_NOT_SUP);
|
||||
break;
|
||||
}
|
||||
|
||||
/* procedure now in progress */
|
||||
plxpsCb.inProgress = TRUE;
|
||||
|
||||
return ATT_SUCCESS;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set the supported features of the pulse oximeter sensor.
|
||||
*
|
||||
* \param feature Feature bitmask.
|
||||
* \param measStatus Measurement status.
|
||||
* \param sensorStatus Sensor status.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsSetFeature(uint16_t feature, uint16_t measStatus, uint32_t sensorStatus)
|
||||
{
|
||||
uint8_t buf[CH_PLXF_MAX_FEATURES_LEN];
|
||||
uint8_t *p = buf;
|
||||
|
||||
UINT16_TO_BSTREAM(p, feature);
|
||||
|
||||
if (feature & CH_PLF_FLAG_MEAS_STATUS_SUP)
|
||||
{
|
||||
UINT16_TO_BSTREAM(p, measStatus);
|
||||
}
|
||||
|
||||
if (feature & CH_PLF_FLAG_SENSOR_STATUS_SUP)
|
||||
{
|
||||
UINT24_TO_BSTREAM(p, sensorStatus);
|
||||
}
|
||||
|
||||
AttsSetAttr(PLXS_FEATURES_HDL, (uint16_t)(p - buf), buf);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Set the CCCD index used by the application for pulse oximeter service characteristics.
|
||||
*
|
||||
* \param plxscCccIdx Pulse Oximeter spot check CCCD index.
|
||||
* \param plxcCccIdx Pulse Oximeter continuous CCCD index.
|
||||
* \param racpCccIdx Record access control point CCCD index.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsSetCccIdx(uint8_t plxscCccIdx, uint8_t plxcCccIdx, uint8_t racpCccIdx)
|
||||
{
|
||||
plxpsCb.plxscCccIdx = plxscCccIdx;
|
||||
plxpsCb.plxcCccIdx = plxcCccIdx;
|
||||
plxpsCb.racpCccIdx = racpCccIdx;
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Start periodic pulse oximeter measurement. This function starts a timer to perform
|
||||
* periodic measurements.
|
||||
*
|
||||
* \param connId DM connection identifier.
|
||||
* \param timerEvt WSF event designated by the application for the timer.
|
||||
* \param plxmCccIdx Index of pulse oximeter CCC descriptor in CCC descriptor handle table.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsMeasStart(dmConnId_t connId, uint8_t timerEvt, uint8_t plxmCccIdx)
|
||||
{
|
||||
/* initialize control block */
|
||||
plxpsCb.measTimer.msg.param = connId;
|
||||
plxpsCb.measTimer.msg.event = timerEvt;
|
||||
plxpsCb.measTimer.msg.status = plxmCccIdx;
|
||||
|
||||
/* start timer */
|
||||
WsfTimerStartMs(&plxpsCb.measTimer, plxpsCb.pCfg->period);
|
||||
}
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Stop periodic pulse oximeter measurement.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void PlxpsMeasStop(void)
|
||||
{
|
||||
WsfTimerStop(&plxpsCb.measTimer);
|
||||
}
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \file
|
||||
*
|
||||
* \brief Pulse Oximeter profile sensor internal interfaces.
|
||||
*
|
||||
* Copyright (c) 2012-2018 Arm Ltd.
|
||||
*
|
||||
* Copyright (c) 2019 Packetcraft, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
#ifndef PLXPS_MAIN_H
|
||||
#define PLXPS_MAIN_H
|
||||
|
||||
#include "app_hw.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*! \addtogroup PULSE_OXIMETER_PROFILE
|
||||
* \{ */
|
||||
|
||||
/**************************************************************************************************
|
||||
Macros
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Minimum RACP write length */
|
||||
#define PLXPS_RACP_MIN_WRITE_LEN 2
|
||||
|
||||
/*! \brief RACP response length */
|
||||
#define PLXPS_RACP_RSP_LEN 4
|
||||
|
||||
/*! \brief Pulse Oximeter RACP number of stored records response length */
|
||||
#define PLXPS_RACP_NUM_REC_RSP_LEN 4
|
||||
|
||||
/*! \brief RACP operand maximum length */
|
||||
#define PLXPS_OPERAND_MAX ((CH_RACP_GLS_FILTER_TIME_LEN * 2) + 1)
|
||||
|
||||
/**************************************************************************************************
|
||||
Data Types
|
||||
**************************************************************************************************/
|
||||
|
||||
/*! \brief Pulse Oximeter measurement record */
|
||||
typedef struct
|
||||
{
|
||||
plxpScm_t spotCheck; /*!< \brief Pulse Oximeter spot check measurement */
|
||||
} plxpsRec_t;
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Initialize the pulse oximeter record database.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsDbInit(void);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the next record that matches the given filter parameters that follows
|
||||
* the given current record.
|
||||
*
|
||||
* \param oper Operator.
|
||||
* \param pCurrRec Pointer to current record.
|
||||
* \param pRec Return pointer to next record, if found.
|
||||
*
|
||||
* \return \ref CH_RACP_RSP_SUCCESS if a record is found, otherwise an error status is returned.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t plxpsDbGetNextRecord(uint8_t oper, plxpsRec_t *pCurrRec, plxpsRec_t **pRec);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Delete records that match the given filter parameters.
|
||||
*
|
||||
* \param oper Operator.
|
||||
*
|
||||
* \return \ref CH_RACP_RSP_SUCCESS if records deleted, otherwise an error status is returned.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t plxpsDbDeleteRecords(uint8_t oper);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Get the number of records matching the filter parameters.
|
||||
*
|
||||
* \param oper Operator.
|
||||
* \param pNumRec Returns number of records which match filter parameters.
|
||||
|
||||
*
|
||||
* \return RACP status.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
uint8_t plxpsDbGetNumRecords(uint8_t oper, uint8_t *pNumRec);
|
||||
|
||||
/*************************************************************************************************/
|
||||
/*!
|
||||
* \brief Generate a new record.
|
||||
*
|
||||
* \return None.
|
||||
*/
|
||||
/*************************************************************************************************/
|
||||
void plxpsDbGenerateRecord(void);
|
||||
|
||||
|
||||
/*! \} */ /* PULSE_OXIMETER_PROFILE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* PLXPS_MAIN_H */
|
||||
Reference in New Issue
Block a user