146 lines
3.6 KiB
C
146 lines
3.6 KiB
C
#include "ppg_pah8001.h"
|
|
|
|
#define PAH8001_R_CONFIG ((0U << 8U) | 0x06)
|
|
#define PAH8001_R_CONFIG_RESET_Pos 7
|
|
#define PAH8001_R_CONFIG_RESET_Msk (1U << PAH8001_R_CONFIG_RESET_Pos)
|
|
#define PAH8001_R_CONFIG_POWERDOWN_Pos 3
|
|
#define PAH8001_R_CONFIG_POWERDOWN_Msk (1U << PAH8001_R_CONFIG_POWERDOWN_Pos)
|
|
|
|
#define PAH8001_R_TOUCH_DET ((0U << 8U) | 0x59)
|
|
#define PAH8001_R_TOUCH_DET_DETECTED_Pos 7
|
|
#define PAH8001_R_TOUCH_DET_DETECTED_Msk (1U << PAH8001_R_TOUCH_DET_DETECTED_Pos)
|
|
|
|
#define PAH8001_R_HR_ALG_A ((1U << 8U) | 0x1A)
|
|
|
|
#define PAH8001_R_HR_ALG_C ((1U << 8U) | 0x1C)
|
|
|
|
#define PAH8001_ERROR_CHECK(x) \
|
|
if (x != IMS_SUCCESS) return IMS_FAIL
|
|
|
|
static ims_ret_t ims_pah8001_register_write(ims_pah8001_t *pah, const uint16_t addr, uint8_t data) {
|
|
ims_ret_t ret;
|
|
|
|
uint8_t tx_buf[] = {0x7F, (addr >> 8U)};
|
|
|
|
ims_i2c_xfer_desc_t xfer_desc = {
|
|
.tx_data = tx_buf,
|
|
.tx_size = 2U,
|
|
.rx_data = NULL,
|
|
.rx_size = 0U,
|
|
};
|
|
|
|
/* Switch register bank */
|
|
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
|
if (ret != IMS_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
tx_buf[0] = (addr & 0xFFU);
|
|
tx_buf[1] = data;
|
|
|
|
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static ims_ret_t ims_pah8001_register_read(ims_pah8001_t *pah, const uint16_t addr, uint8_t *data) {
|
|
ims_ret_t ret;
|
|
|
|
uint8_t tx_buf[] = {0x7F, (addr >> 8U)};
|
|
|
|
ims_i2c_xfer_desc_t xfer_desc = {
|
|
.tx_data = tx_buf,
|
|
.tx_size = 2U,
|
|
.rx_data = NULL,
|
|
.rx_size = 0U,
|
|
};
|
|
|
|
/* Switch register bank */
|
|
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
|
if (ret != IMS_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
tx_buf[0] = (addr & 0xFFU);
|
|
|
|
xfer_desc.tx_size = 1U;
|
|
xfer_desc.rx_data = data;
|
|
xfer_desc.rx_size = 1U;
|
|
|
|
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static ims_ret_t ims_pah8001_reset(ims_pah8001_t *pah) {
|
|
uint8_t wdata = PAH8001_R_CONFIG_RESET_Msk | 2U;
|
|
PAH8001_ERROR_CHECK(ims_pah8001_register_write(pah, PAH8001_R_CONFIG, wdata));
|
|
|
|
pah->cb.delay(pah->pdev, 5);
|
|
|
|
wdata = PAH8001_R_CONFIG_POWERDOWN_Msk | 2U;
|
|
PAH8001_ERROR_CHECK(ims_pah8001_register_write(pah, PAH8001_R_CONFIG, wdata));
|
|
|
|
|
|
pah->cb.delay(pah->pdev, 5);
|
|
|
|
return IMS_SUCCESS;
|
|
}
|
|
|
|
ims_ret_t ims_pah8001_init(ims_pah8001_t *pah) {
|
|
PAH8001_ERROR_CHECK(ims_pah8001_reset(pah));
|
|
return IMS_SUCCESS;
|
|
}
|
|
|
|
ims_ret_t ims_pah8001_power(ims_pah8001_t *pah, const bool on) {
|
|
ims_ret_t ret;
|
|
uint8_t wdata;
|
|
|
|
ret = ims_pah8001_register_read(pah, PAH8001_R_CONFIG, &wdata);
|
|
if (ret != IMS_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
if (!on) {
|
|
wdata |= PAH8001_R_CONFIG_POWERDOWN_Msk;
|
|
} else {
|
|
wdata &= ~PAH8001_R_CONFIG_POWERDOWN_Msk;
|
|
}
|
|
|
|
return ims_pah8001_register_write(pah, PAH8001_R_CONFIG, wdata);
|
|
}
|
|
|
|
ims_ret_t ims_pah8001_touched(ims_pah8001_t *pah, bool *touched) {
|
|
ims_ret_t ret;
|
|
uint8_t rdata;
|
|
|
|
ret = ims_pah8001_register_read(pah, PAH8001_R_TOUCH_DET, &rdata);
|
|
if (ret != IMS_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
if (rdata & PAH8001_R_TOUCH_DET_DETECTED_Msk) {
|
|
*touched = true;
|
|
} else {
|
|
*touched = false;
|
|
}
|
|
|
|
return IMS_SUCCESS;
|
|
}
|
|
|
|
ims_ret_t ims_pah8001_read_alg_hr(ims_pah8001_t *pah, ims_pah8001_alg_t alg, uint8_t *hr) {
|
|
uint16_t rreg;
|
|
|
|
switch (alg) {
|
|
case IMS_PPG_ALG_A:
|
|
rreg = PAH8001_R_HR_ALG_A;
|
|
break;
|
|
case IMS_PPG_ALG_C:
|
|
rreg = PAH8001_R_HR_ALG_C;
|
|
break;
|
|
default:
|
|
return IMS_FAIL;
|
|
}
|
|
|
|
return ims_pah8001_register_read(pah, rreg, hr);
|
|
} |