#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, ®); 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, ®); 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, ®); 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, ®); 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 = ®, .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); }