imsensors/src/franklin/franklin_as3935.c

169 lines
3.8 KiB
C

#include "franklin_as3935.h"
static ims_ret_t ims_as3935_mode_set(ims_as3935_t *ltn, ims_as3935_mode_t mode);
static ims_ret_t ims_as3935_reg_preset(ims_as3935_t *ltn);
static ims_ret_t ims_as3935_calibrate_rco(ims_as3935_t *ltn);
static ims_ret_t ims_as3935_register_read(ims_as3935_t *ltn, uint8_t reg, uint8_t *data);
static ims_ret_t ims_as3935_register_write(ims_as3935_t *ltn, uint8_t reg, uint8_t data);
ims_ret_t ims_as3935_init(ims_as3935_t *ltn) {
ims_ret_t ret;
ret = ims_as3935_mode_set(ltn, IMS_AS3935_MODE_POWER_DOWN);
if (ret != IMS_SUCCESS) {
return ret;
}
ret = ims_as3935_reg_preset(ltn);
if (ret != IMS_SUCCESS) {
return ret;
}
ret = ims_as3935_mode_set(ltn, IMS_AS3935_MODE_ACTIVE);
if (ret != IMS_SUCCESS) {
return ret;
}
ret = ims_as3935_calibrate_rco(ltn);
if (ret != IMS_SUCCESS) {
return ret;
}
uint8_t irq_status;
ret = ims_as3935_get_irq_status(ltn, &irq_status);
return ret;
}
ims_ret_t ims_as3935_get_noise_floor(ims_as3935_t *ltn, uint8_t *nf) {
ims_ret_t ret;
uint8_t reg;
ret = ims_as3935_register_read(ltn, 0x01U, &reg);
if (ret != IMS_SUCCESS) {
return ret;
}
*nf = (reg >> 4U) & 0x07U;
return IMS_SUCCESS;
}
ims_ret_t ims_as3935_set_noise_floor(ims_as3935_t *ltn, uint8_t nf) {
ims_ret_t ret;
uint8_t reg;
ret = ims_as3935_register_read(ltn, 0x01U, &reg);
if (ret != IMS_SUCCESS) {
return ret;
}
reg &= ~(0x07U << 4U);
reg |= ((nf & 0x07U) << 4U);
ret = ims_as3935_register_write(ltn, 0x01U, reg);
return ret;
}
ims_ret_t ims_as3935_get_irq_status(ims_as3935_t *ltn, uint8_t *irq_status) {
ims_ret_t ret;
uint8_t reg;
ret = ims_as3935_register_read(ltn, 0x03U, &reg);
if (ret != IMS_SUCCESS) {
return ret;
}
*irq_status = reg & 0x0FU;
return IMS_SUCCESS;
}
static ims_ret_t ims_as3935_mode_set(ims_as3935_t *ltn, ims_as3935_mode_t mode) {
ims_ret_t ret;
uint8_t reg;
ret = ims_as3935_register_read(ltn, 0x00, &reg);
if (ret != IMS_SUCCESS) {
return ret;
}
reg &= ~(0x01U);
reg |= mode;
ret = ims_as3935_register_write(ltn, 0x00, reg);
return ret;
}
static ims_ret_t ims_as3935_reg_preset(ims_as3935_t *ltn) {
ims_ret_t ret;
ret = ims_as3935_register_write(ltn, 0x3C, 0x96);
return ret;
}
static ims_ret_t ims_as3935_calibrate_rco(ims_as3935_t *ltn) {
ims_ret_t ret;
ret = ims_as3935_register_write(ltn, 0x3D, 0x96);
if (ret != IMS_SUCCESS) {
return ret;
}
uint8_t trco_calib;
uint8_t srco_calib;
for (uint8_t i = 0; i < 32; i++) {
ret = ims_as3935_register_read(ltn, 0x3A, &trco_calib);
if (ret != IMS_SUCCESS) {
return ret;
}
ret = ims_as3935_register_read(ltn, 0x3B, &srco_calib);
if (ret != IMS_SUCCESS) {
return ret;
}
/* Calibration failed */
if ((trco_calib & (1U << 6U)) || (srco_calib & (1U << 6U))) {
return IMS_FAIL;
}
if ((trco_calib & (1U << 7U)) && (srco_calib & (1U << 7U))) {
return IMS_SUCCESS;
}
ltn->cb.delay(ltn->pdev, 5);
}
/* Timed out */
return IMS_FAIL;
}
static ims_ret_t ims_as3935_register_read(ims_as3935_t *ltn, uint8_t reg, uint8_t *data) {
ims_i2c_xfer_desc_t xfer_desc = {
.tx_data = &reg,
.tx_size = 1U,
.rx_data = data,
.rx_size = 1U,
};
return ltn->cb.i2c_xfer(ltn->pdev, &xfer_desc);
}
static ims_ret_t ims_as3935_register_write(ims_as3935_t *ltn, uint8_t reg, uint8_t data) {
uint8_t tx_buf[2] = {reg, data};
ims_i2c_xfer_desc_t xfer_desc = {
.tx_data = tx_buf,
.tx_size = 2U,
.rx_data = NULL,
.rx_size = 0U,
};
return ltn->cb.i2c_xfer(ltn->pdev, &xfer_desc);
}