最近在开发关于呼吸监测仪的血氧模块采集协议及数据处理算法,这里就分享一下关于这期间的一些流程!
具体步骤分别为
1.编写关于通讯协议的驱动方式
2.编写数据协议的解析算法
3.编写关于协议数据解析后的接收传输协议处理
- 首先是了解关于与检测模块的通讯方式:
比较常见的通讯模式有以下几种:
UART、UASRT、SPI、I2C、CAN等通讯方式,相关驱动可以去找例程,这里就串口为例:
以下为串口驱动的应用层:(具体的驱动代码可以参考我的另一篇文章:https://blog.youkuaiyun.com/AN15778423590/article/details/124851445?spm=1001.2014.3001.5502)
#include "SpO2DrvSatex.h"
#include "main.h"
#include "stdint.h"
#include <stdlib.h>
SpO2DrvSatex * SpO2DrvSatex::_instance = NULL;
UART_HandleTypeDef huart2;
uint8_t _rcvBuf[1] = {0};
SpO2DrvSatex::SpO2DrvSatex()
:_ringBuf(512),_pr(0), _spo2(0), _error(0),_connect(0),_timeoutCnt(0)
{
_rcvBuf[0] = 0;
_instance = this;
}
SpO2DrvSatex::~SpO2DrvSatex()
{
}
static void UART2_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (SpO2DrvSatex::Instance())
{
SpO2DrvSatex::Instance()->rcvData();
}
}
static void USART2_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART2)
{
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
}
}
static void USART2_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART2)
{
__HAL_RCC_USART2_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
HAL_NVIC_DisableIRQ(USART2_IRQn);
}
}
static void MX_USART2_UART_Init(void)
{
huart2.RxCpltCallback = UART2_RxCpltCallback;
huart2.MspInitCallback = USART2_MspInit;
huart2.MspDeInitCallback = USART2_MspDeInit;
huart2.Instance = USART2;
huart2.Init.BaudRate = 9600;
huart2.Init.WordLength = UART_WORDLENGTH_9B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_ODD;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
huart2.RxCpltCallback = UART2_RxCpltCallback;
}
int SpO2DrvSatex::CheckSum(uint8_t *buf, int len)
{
uint8_t sum = 0;
for(int i = 1; i<len-1; i++)
{
sum += buf[i];
}
return sum;
}
int SpO2DrvSatex::CheckEstimate(uint8_t *buf, int len)
{
uint8_t sum = 0;
sum = CheckSum(buf,len);
if(sum != buf[len-1])
{
return 1;
}
else
{
return 0;
}
}
void SpO2DrvSatex::rcvData()
{
_ringBuf.pushData(_rcvBuf[0]);
_rcvBuf[0] = 0;
HAL_UART_Receive_IT(&huart2, _rcvBuf, 1);
}
void SpO2DrvSatex::drvInit()
{
MX_USART2_UART_Init();
HAL_UART_Receive_IT(&huart2, _rcvBuf, 1);
}
void SpO2DrvSatex::handleEvent(uint8_t *buf, int len)
{
uint8_t cmdId = buf[4];
int flag = 0;
flag = CheckEstimate(buf,len);
if (flag)
{
return;
}
_timeoutCnt = 0;
_connect = 1;
if (cmdId == 0x81)
{
beginHandshake();
beginSelftest();
}
if (cmdId == 0x85)
{
_error=buf[14]&0x20;
_pr = (buf[10] << 8) | buf[9];
_spo2 = buf[11];
}
}
void SpO2DrvSatex::handleProtocol()
{
int loopCnt = 0;
while (_ringBuf.length() >= 10)
{
loopCnt++;
if (loopCnt > 50)
break;
uint8_t head = _ringBuf[0];
if (head != 0xFA || _ringBuf[2] != 0x03)
{
_ringBuf.popData();
continue;
}
else
{
int len = _ringBuf[1];
if (_ringBuf.length() >= len)
{
uint8_t *buf = new uint8_t[len];
for (int i =0 ; i <= len ; i++)
{
buf[i] = _ringBuf.popData();
}
handleEvent(buf, len);
delete [] buf;
}
else
{
break;
}
}
}
}
void SpO2DrvSatex::handleConnectStatus()
{
static int timeOutCnt = 0;
int32_t cnt = HAL_GetTick();
if (timeOutCnt == 0)
{
timeOutCnt = cnt;
return;
}
if (cnt - timeOutCnt >= 1000)
{
timeOutCnt = cnt;
_timeoutCnt++;
}
if (_timeoutCnt >= 5)
{
_connect = 0;
}
}
void SpO2DrvSatex::drvLoopRun()
{
handleConnectStatus();
handleProtocol();
}
void SpO2DrvSatex::beginHandshake()
{
uint8_t _tsiBuf[10]={0xFA,0x0A,0x03,0x01,0x01,0xEE,0x00,0x00,0x00};
int add = sizeof(_tsiBuf)/sizeof (uint8_t);
_tsiBuf[9]=CheckSum(_tsiBuf,add);
for(int i=0;i<10;i++)
{
HAL_UART_Transmit(&huart2, &_tsiBuf[i], 10, 100);
}
}
void SpO2DrvSatex::beginSelftest()
{
uint8_t _tsiBuf[10]={0xFA,0x0A,0x03,0x02,0x03,0xEE,0x00,0x00,0x00};
int add = sizeof(_tsiBuf)/sizeof (uint8_t);
_tsiBuf[9]=CheckSum(_tsiBuf,add);
for(int i=0;i<10;i++)
{
HAL_UART_Transmit(&huart2, &_tsiBuf[i], 10, 100);
}
}
uint8_t SpO2DrvSatex::getSelftestResult()
{
return 0;
}
uint8_t SpO2DrvSatex::setPatient(int type)
{
uint8_t _tsiBuf[12]={0xFA,0x0A,0x03,0x02,0x04,0xEE,0x00,0x00,0x00};
int add;
switch(type)
{
case 0:
_tsiBuf[10]=0x00;
add = sizeof(_tsiBuf)/sizeof (uint8_t);
_tsiBuf[11]=CheckSum(_tsiBuf,add);
for(int i=0;i<10;i++)
{
HAL_UART_Transmit(&huart2, &_tsiBuf[i], 11, 100);
}
break;
case 1:
_tsiBuf[10]=0x01;
add = sizeof(_tsiBuf)/sizeof (uint8_t);
_tsiBuf[11]=CheckSum(_tsiBuf,add);
for(int i=0;i<10;i++)
{
HAL_UART_Transmit(&huart2, &_tsiBuf[i], 11, 100);
}
break;
}
return 0;
}
uint8_t SpO2DrvSatex::getSpo2()
{
return _spo2;
}
uint16_t SpO2DrvSatex::getPr()
{
return _pr;
}
uint8_t SpO2DrvSatex::connectStatus()
{
if(_connect==0)
{
return SpO2_DISCONNECT;
}
else
{
return SpO2_CONNECT;
}
}
uint8_t SpO2DrvSatex::errcode()
{
uint8_t ret = 0;
if (_error & 0x20)
{
ret |= (1 << SpO2Error_Sensor_Falloff);
}
if (_error & 0x40)
{
ret |= (1 << SpO2Error_Sensor_Falloff);
}
return ret;
}
uint8_t SpO2DrvSatex::type()
{
return SpO2_WIRED;
}
- 编写数据协议的解析算法
#include "ProtocolSpO2RawData.h"
#include "ProtocolId.h"
#include "Spo2.h"
#include "PatientManager.h"
#include "Spo2def.h"
ProtocolSpO2RawData::ProtocolSpO2RawData(ProtocolManager *pMng)
:_ringBuf(2048),_pr(PR_INVALID_VALUE), _spo2(SPO2_INVALID_VALUE), _error(0),_connect(0),_timeoutCnt(0), ProtocolObj(PROTOCOL_ID_SPO2_RAW_DATA, pMng)
{
}
ProtocolSpO2RawData::~ProtocolSpO2RawData()
{
}
int ProtocolSpO2RawData::handleRcvData(uint8_t *data, uint16_t len)
{
rcvData(data, len);
return len;
}
int ProtocolSpO2RawData::init()
{
SysSpO2->registerSpo2Drv(this);
return 0 ;
}
int ProtocolSpO2RawData::loopRun()
{
handleConnectStatus();
handleProtocol();
return 0;
}
int ProtocolSpO2RawData::CheckSum(uint8_t *buf, int len)
{
uint8_t sum = 0;
for(int i = 1; i < len-1; i++)
{
sum += buf[i];
}
return sum;
}
int ProtocolSpO2RawData::CheckEstimate(uint8_t *buf, int len)
{
uint8_t sum = 0;
sum = CheckSum(buf, len);
if(sum != buf[len-1])
{
return 1;
}
else
{
return 0;
}
}
void ProtocolSpO2RawData::rcvData(uint8_t *buf, int len)
{
for (int i = 0; i < len ; i++)
{
_ringBuf.pushData(buf[i]);
}
}
void ProtocolSpO2RawData::drvInit()
{
}
void ProtocolSpO2RawData::parseData(uint8_t *buf, int len)
{
uint8_t cmdId = buf[4];
int sum = 0;
sum = CheckSum(buf,len);
if (sum != buf[len-1])
{
return;
}
_timeoutCnt = 0;
_connect = 1;
if (cmdId == 0x81)
{
beginHandshake();
beginSelftest();
}
if (cmdId == 0x85)
{
_error=buf[14]&0x20;
_pr = (buf[10] << 8) | buf[9];
_spo2 = buf[11];
}
}
void ProtocolSpO2RawData::handleProtocol()
{
int loopCnt = 0;
while (_ringBuf.length() >= 10)
{
loopCnt++;
if (loopCnt > 50)
break;
uint8_t head = _ringBuf[0];
if (head != 0xFA || _ringBuf[2] != 0x03)
{
_ringBuf.popData();
continue;
}
else
{
int len = _ringBuf[1];
if (len == 0)
{
_ringBuf.popData();
continue;
}
if (_ringBuf.length() >= len)
{
uint8_t *buf = new uint8_t[len];
for (int i = 0 ; i < len ; i++)
{
buf[i] = _ringBuf.popData();
}
parseData(buf, len);
delete [] buf;
}
else
{
break;
}
}
}
}
void ProtocolSpO2RawData::handleConnectStatus()
{
static int timeOutCnt = 0;
int32_t cnt = HAL_GetTick();
if (timeOutCnt == 0)
{
timeOutCnt = cnt;
return;
}
if (cnt - timeOutCnt >= 1000)
{
timeOutCnt = cnt;
_timeoutCnt++;
}
if (_timeoutCnt >= 5)
{
_spo2 = SPO2_INVALID_VALUE;
_pr = PR_INVALID_VALUE;
_error = 0;
_connect = 0;
}
}
void ProtocolSpO2RawData::drvLoopRun()
{
}
void ProtocolSpO2RawData::beginHandshake()
{
uint8_t buf[10] = {0xFA,0x0A,0x03,0x01,0x01,0xEE,0x00,0x00,0x00};
int len = sizeof(buf)/sizeof (uint8_t);
buf[9] = CheckSum(buf, len);
sendData(buf, len);
}
void ProtocolSpO2RawData::beginSelftest()
{
uint8_t buf[10] = {0xFA,0x0A,0x03,0x02,0x03,0xEE,0x00,0x00,0x00};
int len = sizeof(buf)/sizeof (uint8_t);
buf[9] = CheckSum(buf, len);
sendData(buf, len);
}
uint8_t ProtocolSpO2RawData::getSelftestResult()
{
return 0;
}
uint8_t ProtocolSpO2RawData::setPatient(int type)
{
uint8_t buf[12] = {0xFA,0x0A,0x03,0x02,0x04,0xEE,0x00,0x00,0x00};
int len = sizeof(buf)/sizeof (uint8_t);;
switch(type)
{
case PatientManager::PATIENT_TYPE_ADULT:
buf[10] = 0x00;
buf[11] = CheckSum(buf, len);
sendData(buf, len);
break;
case PatientManager::PATIENT_TYPE_KID:
buf[10] = 0x01;
buf[11]=CheckSum(buf, len);
sendData(buf, len);
break;
}
return len;
}
uint8_t ProtocolSpO2RawData::getSpo2()
{
uint8_t spo2 = _spo2;
if (_spo2 == 0x7F )
{
spo2 = SPO2_INVALID_VALUE;
}
return spo2;
}
uint16_t ProtocolSpO2RawData::getPr()
{
uint16_t pr = _pr;
if (_pr == 0x1FF)
{
pr = PR_INVALID_VALUE;
};
return pr;
}
uint8_t ProtocolSpO2RawData::connectStatus()
{
if(_connect == 0)
{
return SpO2_DISCONNECT;
}
else
{
return SpO2_CONNECT;
}
}
uint8_t ProtocolSpO2RawData::errcode()
{
uint8_t ret = 0;
if (_error & 0x20)
{
ret |= (1 << SpO2Error_Sensor_Falloff);
}
if (_error & 0x40)
{
ret |= (1 << SpO2Error_Sensor_Falloff);
}
return ret;
}
uint8_t ProtocolSpO2RawData::type()
{
return SpO2_WIRED;
}
#include "ProtocolDrvUart.h"
#include "main.h"
#include "ProtocolManager.h"
ProtocolDrvUart * ProtocolDrvUart::_instance = NULL;
UART_HandleTypeDef huart6;
static void UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (ProtocolDrvUart::Instance())
{
ProtocolDrvUart::Instance()->receiveData();
}
}
static void UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART6)
{
__HAL_RCC_USART6_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}
}
static void UART_MspDeInit(UART_HandleTypeDef* huart)
{
if(huart->Instance == USART6)
{
__HAL_RCC_USART6_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6|GPIO_PIN_7);
HAL_NVIC_DisableIRQ(USART6_IRQn);
}
}
static void UARTErrorCallback(struct __UART_HandleTypeDef *huart)
{
if (huart->ErrorCode & HAL_UART_ERROR_ORE)
{
__HAL_UART_CLEAR_OREFLAG(huart);
}
log_info("-------------------error:%d\n", huart->ErrorCode);
}
static void MX_USART6_UART_Init(void)
{
huart6.MspInitCallback = UART_MspInit;
huart6.MspDeInitCallback= UART_MspDeInit;
huart6.Instance = USART6;
huart6.Init.BaudRate = 38400;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart6) != HAL_OK)
{
Error_Handler();
}
huart6.RxCpltCallback = UART_RxCpltCallback;
huart6.ErrorCallback = UARTErrorCallback;
}
static void CocCpuResetGpioInit()
{
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOI_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
}
static void CocCpuReset()
{
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_3, GPIO_PIN_SET);
HAL_Delay(2);
HAL_GPIO_WritePin(GPIOI, GPIO_PIN_3, GPIO_PIN_RESET);
}
ProtocolDrvUart::ProtocolDrvUart()
{
_rcvBuf[0] = 0;
}
ProtocolDrvUart::~ProtocolDrvUart()
{
}
int ProtocolDrvUart::sendData(uint8_t *buf, uint16_t len)
{
if (buf)
{
int ret = HAL_UART_Transmit(&huart6, buf, len, 100);
if (ret == HAL_OK)
{
return len;
}
}
return -1;
}
void ProtocolDrvUart::protocolDrvInit()
{
MX_USART6_UART_Init();
HAL_NVIC_SetPriority(USART6_IRQn, 6, 0);
HAL_NVIC_EnableIRQ(USART6_IRQn);
HAL_UART_Receive_IT(&huart6, _rcvBuf, 1);
ready();
_instance = this;
}
void ProtocolDrvUart::receiveData()
{
rcvData(_rcvBuf, 1);
_rcvBuf[0] = 0;
HAL_UART_Receive_IT(&huart6, _rcvBuf, 1);
}
- 编写关于协议数据解析后的接收传输协议
#include "ProtocolManager.h"
#include "ProtocolHeartBeat.h"
#include "ProtocolAlarm.h"
#include "ProtocolSpo2.h"
#include "ProtocolDrvUart.h"
#include "ProtocolSpO2RawData.h"
#include "ProtocolWireless.h"
ProtocolManager * ProtocolManager::_instance = NULL;
ProtocolManager::ProtocolManager()
:_circleBuf(2048)
{
_allProtocolObjs.clear();
_proDrv = NULL;
_sendItems.clear();
}
ProtocolManager::~ProtocolManager()
{
_sendItems.clear();
}
int ProtocolManager::registerProtocol(ProtocolObj *obj)
{
int ret = 0;
if (!obj)
{
return 1;
}
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (;it != _allProtocolObjs.end(); it++)
{
if (*it == obj)
{
ret = 1;
return ret;
}
}
obj->init();
_allProtocolObjs.push_back(obj);
return ret;
}
int ProtocolManager::unregisterProtocol(ProtocolObj *obj)
{
int ret = 1;
if (!obj)
{
return ret;
}
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (;it != _allProtocolObjs.end(); it++)
{
if (*it == obj)
{
ret = 0;
_allProtocolObjs.erase(it);
obj->deinit();
return ret;
}
}
return ret;
}
int ProtocolManager::loopRun()
{
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (;it != _allProtocolObjs.end(); it++)
{
ProtocolObj *obj = *it;
if (obj)
{
obj->loopRun();
}
}
handleProtocol();
handleSendItems();
return 0;
}
void ProtocolManager::init()
{
ProtocolDrvUart *drv = new ProtocolDrvUart();
setProDrv(drv);
ProtocolHeartBeat *pHeartBeat = new ProtocolHeartBeat(this);
registerProtocol(pHeartBeat);
ProtocolAlarm *pAlarm = new ProtocolAlarm(this);
registerProtocol(pAlarm);
#if 0
ProtocolSpo2 *pSpo2 = new ProtocolSpo2(this);
registerProtocol(pSpo2);
#endif
ProtocolSpO2RawData *pSpo2RawData = new ProtocolSpO2RawData(this);
registerProtocol(pSpo2RawData);
ProtocolWireless *pWireless = new ProtocolWireless(this);
registerProtocol(pWireless);
}
void ProtocolManager::setProDrv(ProtocolDrv *drv)
{
if (drv)
{
drv->protocolDrvInit();
_proDrv = drv;
}
}
int ProtocolManager::checkData(uint8_t *buf, int len)
{
int sum = 0;
for (int i = 0; i < len; i++)
{
sum += buf[i];
}
return sum;
}
#if 0
void ProtocolManager::handleProtocol()
{
#if 0
while (_circleBuf.length())
{
uint8_t c = _circleBuf.popData();
log_info("----------------:%c\n", c);
}
#endif
int loopCnt = 0;
while (_circleBuf.length() >= 7)
{
loopCnt++;
if (loopCnt >= 50)
{
break;
}
uint8_t startCh = _circleBuf[0];
if (startCh == 0xAA)
{
uint16_t len = (_circleBuf[3] << 8) | _circleBuf[4];
if (len > 500)
{
_circleBuf.popData();
continue;
}
if (_circleBuf.length() < len + 7)
{
break;
}
else
{
uint8_t *buf = new uint8_t[len + 7];
for (int i = 0; i < len + 7; i++)
{
buf[i] = _circleBuf.popData();
}
int checkRcv = (buf[len + 5] << 8) | buf[len+6];
int checkRes = checkData(&buf[5], len);
if (checkRcv != checkRes)
{
log_info("Rcv an invalid packet\n");
}
else
{
uint16_t cmd = (buf[1] << 8) | buf[2];
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (; it != _allProtocolObjs.end(); it++)
{
ProtocolObj *obj = *it;
if (obj)
{
if (obj->getId() == cmd)
{
obj->handleRcvData(&buf[5], len);
}
}
}
}
delete [] buf;
}
}
else
{
_circleBuf.popData();
}
}
}
#endif
void ProtocolManager::handleProtocol()
{
int loopCnt = 0;
while (_circleBuf.length() >= 7)
{
loopCnt++;
if (loopCnt >= 50)
{
break;
}
uint8_t startCh1 = _circleBuf[0];
uint8_t startCh2 = _circleBuf[1];
if (startCh1 == 0xAA && startCh2 == 0xFF)
{
uint16_t len = (_circleBuf[3] << 8) | _circleBuf[4];
if (len > 500)
{
_circleBuf.popData();
continue;
}
if (_circleBuf.length() < len + 7)
{
break;
}
else
{
uint8_t *buf = new uint8_t[len + 7];
for (int i = 0; i < len + 7; i++)
{
buf[i] = _circleBuf[i];
}
int checkRcv = (buf[len + 5] << 8) | buf[len+6];
int checkRes = checkData(&buf[5], len);
if (checkRcv != checkRes)
{
_circleBuf.popData();
log_info("Rcv an invalid packet\n");
}
else
{
for (int i = 0; i < len + 7; i++)
{
_circleBuf.popData();
}
uint16_t cmd = buf[2];
list<ProtocolObj *>::iterator it = _allProtocolObjs.begin();
for (; it != _allProtocolObjs.end(); it++)
{
ProtocolObj *obj = *it;
if (obj)
{
if (obj->getId() == cmd)
{
obj->handleRcvData(&buf[5], len);
}
}
}
}
delete [] buf;
}
}
else
{
_circleBuf.popData();
}
}
}
#if 0
void ProtocolManager::handleSendItems()
{
#if 1
if (!_proDrv)
return;
#endif
int loopCnt = 0;
while(!_sendItems.empty())
{
loopCnt++;
if (loopCnt > 10)
break;
list<ProtocolSendItem *>::iterator it = _sendItems.begin();
ProtocolSendItem *item = *it;
_lock.lock();
_sendItems.erase(it);
_lock.unlock();
if (_proDrv)
_proDrv->sendData(item->buf, item->len);
delete [] item->buf;
delete item;
}
}
#endif
void ProtocolManager::handleSendItems()
{
#if 1
if (!_proDrv)
return;
#endif
static int tick = 0;
int curTick = HAL_GetTick();
if (curTick - tick < 100)
{
return;
}
tick = curTick;
if(!_sendItems.empty())
{
list<ProtocolSendItem *>::iterator it = _sendItems.begin();
ProtocolSendItem *item = *it;
_lock.lock();
_sendItems.erase(it);
_lock.unlock();
_proDrv->sendData(item->buf, item->len);
delete [] item->buf;
delete item;
}
}
#if 0
int ProtocolManager::sendData(uint8_t *buf, uint16_t len, uint16_t cmd)
{
if (buf)
{
uint16_t sum = 0;
uint16_t sendLen = 1 + 2 + 2 + len + 2;
uint8_t *sendBuf = new uint8_t[sendLen];
sendBuf[0] = 0xAA;
sendBuf[1] = (cmd & 0xFF00)>>8;
sendBuf[2] = (cmd & 0xFF);
sendBuf[3] = (len & 0xFF00)>>8;
sendBuf[4] = (len & 0xFF);
for (int i = 0; i < len; i++)
{
sendBuf[5+ i] = buf[i];
sum += buf[i];
}
sendBuf[5 + len] = (sum & 0xFF00)>>8;
sendBuf[5 + len + 1] = (sum & 0xFF);
#if 0
if (_proDrv && _proDrv->isReady())
_proDrv->sendData(sendBuf, sendLen);
delete sendBuf;
return len;
#endif
ProtocolSendItem *item = new ProtocolSendItem;
item->buf = sendBuf;
item->len = sendLen;
_lock.lock();
_sendItems.push_back(item);
_lock.unlock();
return len;
}
return 0;
}
#endif
int ProtocolManager::sendData(uint8_t *buf, uint16_t len, uint8_t cmd)
{
if (buf)
{
uint16_t sum = 0;
uint16_t sendLen = 1 + 2 + 2 + len + 2;
uint8_t *sendBuf = new uint8_t[sendLen];
sendBuf[0] = 0xAA;
sendBuf[1] = 0xFF;
sendBuf[2] = cmd;
sendBuf[3] = (len & 0xFF00)>>8;
sendBuf[4] = (len & 0xFF);
for (int i = 0; i < len; i++)
{
sendBuf[5+ i] = buf[i];
sum += buf[i];
}
sendBuf[5 + len] = (sum & 0xFF00)>>8;
sendBuf[5 + len + 1] = (sum & 0xFF);
#if 0
if (_proDrv && _proDrv->isReady())
_proDrv->sendData(sendBuf, sendLen);
delete sendBuf;
return len;
#endif
ProtocolSendItem *item = new ProtocolSendItem;
item->buf = sendBuf;
item->len = sendLen;
_lock.lock();
_sendItems.push_back(item);
_lock.unlock();
return len;
}
return 0;
}
int ProtocolManager::rcvData(uint8_t *buf, uint16_t len)
{
int ret = 0;
if (buf)
{
for (int i = 0; i < len; i++)
{
_circleBuf.pushData(buf[i]);
}
ret = len;
}
return ret;
}
#include "ProtocolSpO2RawData.h"
#include "ProtocolId.h"
#include "Spo2.h"
#include "PatientManager.h"
#include "Spo2def.h"
ProtocolSpO2RawData::ProtocolSpO2RawData(ProtocolManager *pMng)
:_ringBuf(2048),_pr(PR_INVALID_VALUE), _spo2(SPO2_INVALID_VALUE), _error(0),_connect(0),_timeoutCnt(0), ProtocolObj(PROTOCOL_ID_SPO2_RAW_DATA, pMng)
{
}
ProtocolSpO2RawData::~ProtocolSpO2RawData()
{
}
int ProtocolSpO2RawData::handleRcvData(uint8_t *data, uint16_t len)
{
rcvData(data, len);
return len;
}
int ProtocolSpO2RawData::init()
{
SysSpO2->registerSpo2Drv(this);
return 0 ;
}
int ProtocolSpO2RawData::loopRun()
{
handleConnectStatus();
handleProtocol();
return 0;
}
int ProtocolSpO2RawData::CheckSum(uint8_t *buf, int len)
{
uint8_t sum = 0;
for(int i = 1; i < len-1; i++)
{
sum += buf[i];
}
return sum;
}
int ProtocolSpO2RawData::CheckEstimate(uint8_t *buf, int len)
{
uint8_t sum = 0;
sum = CheckSum(buf, len);
if(sum != buf[len-1])
{
return 1;
}
else
{
return 0;
}
}
void ProtocolSpO2RawData::rcvData(uint8_t *buf, int len)
{
for (int i = 0; i < len ; i++)
{
_ringBuf.pushData(buf[i]);
}
}
void ProtocolSpO2RawData::drvInit()
{
}
void ProtocolSpO2RawData::parseData(uint8_t *buf, int len)
{
uint8_t cmdId = buf[4];
int sum = 0;
sum = CheckSum(buf,len);
if (sum != buf[len-1])
{
return;
}
_timeoutCnt = 0;
_connect = 1;
if (cmdId == 0x81)
{
beginHandshake();
beginSelftest();
}
if (cmdId == 0x85)
{
_error=buf[14]&0x20;
_pr = (buf[10] << 8) | buf[9];
_spo2 = buf[11];
}
}
void ProtocolSpO2RawData::handleProtocol()
{
int loopCnt = 0;
while (_ringBuf.length() >= 10)
{
loopCnt++;
if (loopCnt > 50)
break;
uint8_t head = _ringBuf[0];
if (head != 0xFA || _ringBuf[2] != 0x03)
{
_ringBuf.popData();
continue;
}
else
{
int len = _ringBuf[1];
if (len == 0)
{
_ringBuf.popData();
continue;
}
if (_ringBuf.length() >= len)
{
uint8_t *buf = new uint8_t[len];
for (int i = 0 ; i < len ; i++)
{
buf[i] = _ringBuf.popData();
}
parseData(buf, len);
delete [] buf;
}
else
{
break;
}
}
}
}
void ProtocolSpO2RawData::handleConnectStatus()
{
static int timeOutCnt = 0;
int32_t cnt = HAL_GetTick();
if (timeOutCnt == 0)
{
timeOutCnt = cnt;
return;
}
if (cnt - timeOutCnt >= 1000)
{
timeOutCnt = cnt;
_timeoutCnt++;
}
if (_timeoutCnt >= 5)
{
_spo2 = SPO2_INVALID_VALUE;
_pr = PR_INVALID_VALUE;
_error = 0;
_connect = 0;
}
}
void ProtocolSpO2RawData::drvLoopRun()
{
}
void ProtocolSpO2RawData::beginHandshake()
{
uint8_t buf[10] = {0xFA,0x0A,0x03,0x01,0x01,0xEE,0x00,0x00,0x00};
int len = sizeof(buf)/sizeof (uint8_t);
buf[9] = CheckSum(buf, len);
sendData(buf, len);
}
void ProtocolSpO2RawData::beginSelftest()
{
uint8_t buf[10] = {0xFA,0x0A,0x03,0x02,0x03,0xEE,0x00,0x00,0x00};
int len = sizeof(buf)/sizeof (uint8_t);
buf[9] = CheckSum(buf, len);
sendData(buf, len);
}
uint8_t ProtocolSpO2RawData::getSelftestResult()
{
return 0;
}
uint8_t ProtocolSpO2RawData::setPatient(int type)
{
uint8_t buf[12] = {0xFA,0x0A,0x03,0x02,0x04,0xEE,0x00,0x00,0x00};
int len = sizeof(buf)/sizeof (uint8_t);;
switch(type)
{
case PatientManager::PATIENT_TYPE_ADULT:
buf[10] = 0x00;
buf[11] = CheckSum(buf, len);
sendData(buf, len);
break;
case PatientManager::PATIENT_TYPE_KID:
buf[10] = 0x01;
buf[11]=CheckSum(buf, len);
sendData(buf, len);
break;
}
return len;
}
uint8_t ProtocolSpO2RawData::getSpo2()
{
uint8_t spo2 = _spo2;
if (_spo2 == 0x7F )
{
spo2 = SPO2_INVALID_VALUE;
}
return spo2;
}
uint16_t ProtocolSpO2RawData::getPr()
{
uint16_t pr = _pr;
if (_pr == 0x1FF)
{
pr = PR_INVALID_VALUE;
};
return pr;
}
uint8_t ProtocolSpO2RawData::connectStatus()
{
if(_connect == 0)
{
return SpO2_DISCONNECT;
}
else
{
return SpO2_CONNECT;
}
}
uint8_t ProtocolSpO2RawData::errcode()
{
uint8_t ret = 0;
if (_error & 0x20)
{
ret |= (1 << SpO2Error_Sensor_Falloff);
}
if (_error & 0x40)
{
ret |= (1 << SpO2Error_Sensor_Falloff);
}
return ret;
}
uint8_t ProtocolSpO2RawData::type()
{
return SpO2_WIRED;
}