Added AS3935 driver.
continuous-integration/drone/push Build is passing Details

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-07-30 16:21:46 +08:00
parent 11283beab7
commit 8280fe22c9
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
3 changed files with 208 additions and 0 deletions

View File

@ -8,6 +8,7 @@ set(IMSENSORS_SRCS
"src/als/als_ltr_303als.c"
"src/dht/dht_aht10.c"
"src/dht/dht_bme280.c"
"src/franklin/franklin_as3935.c"
"src/imu/imu_lsm6dsl.c"
)
@ -15,6 +16,7 @@ set(IMSENSORS_INCS
"include/imsensors/common"
"include/imsensors/als"
"include/imsensors/dht"
"include/imsensors/franklin"
"include/imsensors/imu"
)

View File

@ -0,0 +1,37 @@
#ifndef IMS_AS3935_H
#define IMS_AS3935_H
#include "imsensors/common/sensors_common.h"
typedef enum {
IMS_AS3935_MODE_ACTIVE = 0U,
IMS_AS3935_MODE_POWER_DOWN = 1U,
} ims_as3935_mode_t;
typedef enum {
IMS_AS3935_AFE_INDOOR = 0x12U,
IMS_AS3935_AFE_OUTDOOR = 0x0EU,
} ims_as3935_afe_mode_t;
typedef enum {
IMS_AS3935_IRQ_TYPE_NH = 0x01U, /* Noise level too high */
IMS_AS3935_IRQ_TYPE_D = 0x04U, /* Disturber detected */
IMS_AS3935_IRQ_TYPE_L = 0x08U, /* Lightning detected */
} ims_as3935_irq_type_t;
typedef struct {
ims_i2c_xfer_t i2c_xfer;
ims_delay_t delay;
} ims_as3935_cb_t;
typedef struct {
void *pdev;
ims_as3935_cb_t cb;
} ims_as3935_t;
ims_ret_t ims_as3935_init(ims_as3935_t *ltn);
ims_ret_t ims_as3935_get_noise_floor(ims_as3935_t *ltn, uint8_t *nf);
ims_ret_t ims_as3935_set_noise_floor(ims_as3935_t *ltn, uint8_t nf);
ims_ret_t ims_as3935_get_irq_status(ims_as3935_t *ltn, uint8_t *irq_status);
#endif // IMS_AS3935_H

View File

@ -0,0 +1,169 @@
#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);
}