/** * \file b_drv_qmc5883l.c * \version v0.0.1 * \date 2023-11-06 * \author miniminiminini (405553848@qq.com) * \brief * * Copyright (c) 2023 by miniminiminini. All Rights Reserved. */ /* Includes ----------------------------------------------*/ #include "drivers/inc/b_drv_qmc5883l.h" #include <string.h> #include "utils/inc/b_util_log.h" /** * \defgroup QMC5883L_Private_TypesDefinitions * \{ */ /** * } */ /** * \defgroup QMC5883L_Private_Defines * \{ */ #define DRIVER_NAME QMC5883L #define QMC5883L_ID 0xFF #define MAG_X_REG_L 0X00 #define MAG_X_REG_H 0X01 #define MAG_Y_REG_L 0X02 #define MAG_Y_REG_H 0X03 #define MAG_Z_REG_L 0X04 #define MAG_Z_REG_H 0X05 #define STATUS_REG 0X06 #define TEMP_L_REG 0X07 #define TEMP_H_REG 0X08 #define CONTROL_1_REG 0X09 #define CONTROL_2_REG 0X0A #define PERIOD_REG 0X0B #define CHIP_ID_REG 0X0D #define MAG_DATA_LEN 6 /** * } */ /** * \defgroup QMC5883L_Private_Macros * \{ */ #define U82U16(msb, lsb) ((((msb)&0xffff) << 8) | (((lsb)&0xffff))) /** * } */ /** * \defgroup QMC5883L_Private_Variables * \{ */ bDRIVER_HALIF_TABLE(bQMC5883L_HalIf_t, DRIVER_NAME); /** * } */ /** * \defgroup QMC5883L_Private_FunctionPrototypes * \{ */ /** * } */ /** * \defgroup QMC5883L_Private_Functions * \{ */ /** * \brief 读寄存器并且判定是否iic失败 * \param pdrv * \param reg * \param data * \param len * \return int -1:失败,0:正常 */ static int _bQMC5883LReadCheckRegs(bDriverInterface_t *pdrv, uint8_t reg, uint8_t *data, uint16_t len) { bDRIVER_GET_HALIF(_if, bQMC5883L_HalIf_t, pdrv); if (bHalI2CMemRead(_if, reg, 1, data, len) < 0) { return -1; } return len; } /** * \brief 写寄存器后再读寄存器,看是否配置成功,若iic失败或者写后再读值不一致则返回失败 * \param pdrv * \param reg * \param data * \param len * \return int -1:失败,0:正常 */ static int _bQMC5883LWriteCheckRegs(bDriverInterface_t *pdrv, uint8_t reg, uint8_t *data, uint16_t len) { uint8_t read_buf[len]; bDRIVER_GET_HALIF(_if, bQMC5883L_HalIf_t, pdrv); memset(read_buf, 0, sizeof(read_buf)); if (bHalI2CMemWrite(_if, reg, 1, data, len) < 0) { return -1; } if (bHalI2CMemRead(_if, reg, 1, read_buf, len) < 0) { return -1; } for (uint16_t i = 0; i < len; i++) { if (read_buf[i] != data[i]) { return -2; } } return len; } static int _bQMC5883LGetID(bDriverInterface_t *pdrv, uint8_t *id) { if (_bQMC5883LReadCheckRegs(pdrv, CHIP_ID_REG, id, 1) < 0) { return -1; } // b_log("QMC5883L id:0x%x\n", id); return 0; } static int _bQMC5883LDefaultCfg(bDriverInterface_t *pdrv) { uint8_t control_1_reg_val = 0x1d; uint8_t period_reg_val = 0x01; uint8_t cfg1_val = 0x40; uint8_t cfg2_val = 0x01; if (_bQMC5883LWriteCheckRegs(pdrv, PERIOD_REG, &period_reg_val, 1) < 0) { return -1; } if (_bQMC5883LWriteCheckRegs(pdrv, 0x21, &cfg2_val, 1) < 0) { return -1; } if (_bQMC5883LWriteCheckRegs(pdrv, 0x20, &cfg1_val, 1) < 0) { return -1; } if (_bQMC5883LWriteCheckRegs(pdrv, CONTROL_1_REG, &control_1_reg_val, 1) < 0) { return -1; } return 0; } static int _bQMC5883LRead(bDriverInterface_t *pdrv, uint32_t off, uint8_t *pbuf, uint32_t len) { uint8_t mag_data[6]; bQMC5883L_3Axis_t *ptmp = (bQMC5883L_3Axis_t *)pbuf; if (len < sizeof(bQMC5883L_3Axis_t)) { return -1; } if (_bQMC5883LReadCheckRegs(pdrv, MAG_X_REG_L, &mag_data[0], MAG_DATA_LEN) < 0) { return -1; } // _bQMC5883LReadCheckRegs(pdrv, MAG_X_REG_L, &mag_data[0], 1); // _bQMC5883LReadCheckRegs(pdrv, MAG_X_REG_H, &mag_data[1], 1); // _bQMC5883LReadCheckRegs(pdrv, MAG_Y_REG_L, &mag_data[2], 1); // _bQMC5883LReadCheckRegs(pdrv, MAG_Y_REG_H, &mag_data[3], 1); // _bQMC5883LReadCheckRegs(pdrv, MAG_Z_REG_L, &mag_data[4], 1); // _bQMC5883LReadCheckRegs(pdrv, MAG_Z_REG_H, &mag_data[5], 1); // b_log("mag_reg_dat:0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", mag_data[0], mag_data[1], // mag_data[2], mag_data[3], mag_data[4], mag_data[5]); ptmp->mag_arr[0] = (float)((short)(U82U16(mag_data[1], mag_data[0]))) / 30.0f; ptmp->mag_arr[1] = (float)((short)(U82U16(mag_data[3], mag_data[2]))) / 30.0f; ptmp->mag_arr[2] = (float)((short)(U82U16(mag_data[5], mag_data[4]))) / 30.0f; // b_log("mag_dat:%f %f %f\n", ptmp->mag_arr[0], ptmp->mag_arr[1], ptmp->mag_arr[2]); return 0; } /** * \brief * \param pdrv * \param cmd * \param param * \return int * -1代表期间iic错误 * 0在bCMD_QMC5883L_WHETHER_NEWDATA_READY下表示有数据 * 1在bCMD_QMC5883L_WHETHER_NEWDATA_READY下表示无数据 */ static int _bQMC5883LCtl(struct bDriverIf *pdrv, uint8_t cmd, void *param) { int retval = -1; uint8_t read_dat = 0; switch (cmd) { case bCMD_QMC5883L_WHETHER_NEWDATA_READY: { if (_bQMC5883LReadCheckRegs(pdrv, STATUS_REG, &read_dat, 1) < 0) { retval = -1; } else { if (read_dat & 0x01) { retval = QMC5883L_NEWDATA_READY; } else { retval = QMC5883L_NEWDATA_NOT_READY; } } } break; case bCMD_QMC5883L_SET_STATUS_ERR: { pdrv->status = -1; retval = 0; } break; default: retval = -1; break; } return retval; } /** * } */ /** * \defgroup QMC5883L_Exported_Functions * \{ */ // int bQMC5883L_Init_0(bDriverInterface_t *pdrv) // { // _bQMC5883LSOFTRESET(pdrv); // bHalDelayMs(50); // return 0; // } int bQMC5883L_Init(bDriverInterface_t *pdrv) { uint8_t id = 0; bDRIVER_STRUCT_INIT(pdrv, DRIVER_NAME, bQMC5883L_Init); pdrv->read = _bQMC5883LRead; pdrv->ctl = _bQMC5883LCtl; if (_bQMC5883LGetID(pdrv, &id) < 0) { return -1; } if (id != QMC5883L_ID) { return -1; } if (_bQMC5883LDefaultCfg(pdrv) < 0) { return -1; } return 0; } // bDRIVER_REG_INIT_0(B_DRIVER_QMC5883L, bQMC5883L_Init_0); #ifdef BSECTION_NEED_PRAGMA #pragma section driver_init #endif bDRIVER_REG_INIT(B_DRIVER_QMC5883L, bQMC5883L_Init); #ifdef BSECTION_NEED_PRAGMA #pragma section #endif /** * } */ /** * } */ /** * } */ /** * } */ /***** Copyright (c) 2023 miniminiminini *****END OF FILE*****/