/* * LSM303DLHC.c * * Created on: Apr 2, 2021 * Author: Think */ #include "LSM303DLHC.h" //Accelerometer sensor I2C address definition static const uint8_t LMS303DLHC_ACCEL_ADDR = 0x19 << 1; //Magnetic sensor I2C address definition static const uint8_t LMS303DLHC_COMP_ADDR = 0x1E << 1; //Accelerometer register definition static const uint8_t _CTRL_REG1_A = 0x20; static const uint8_t _CTRL_REG2_A = 0x21; static const uint8_t _CTRL_REG3_A = 0x22; static const uint8_t _CTRL_REG4_A = 0x23; static const uint8_t _CTRL_REG5_A = 0x24; static const uint8_t _CTRL_REG6_A = 0x25; static const uint8_t _REFERENCE_A = 0x26; static const uint8_t _STATUS_REG_A = 0x27; static const uint8_t _OUT_X_L_A = 0x28; static const uint8_t _OUT_X_H_A = 0x29; static const uint8_t _OUT_Y_L_A = 0x2A; static const uint8_t _OUT_Y_H_A = 0x2B; static const uint8_t _OUT_Z_L_A = 0x2C; static const uint8_t _OUT_Z_H_A = 0x2D; static const uint8_t _FIFO_CTRL_REG_A = 0x2E; static const uint8_t _FIFO_SRC_REG_A = 0x2F; static const uint8_t _INT1_CFG_A = 0X30; static const uint8_t _INT1_SRC_A = 0x31; static const uint8_t _INT1_THS_A = 0x32; static const uint8_t _INT1_DURATION_A = 0x33; static const uint8_t _INT2_CFG_A = 0x34; static const uint8_t _INT2_SRC_A = 0x35; static const uint8_t _INT2_THS_A = 0x36; static const uint8_t _INT2_DURATION_A = 0x37; static const uint8_t _CLICK_CFG_A = 0x38; static const uint8_t _CLICK_SRC_A = 0x39; static const uint8_t _CLICK_THS_A = 0x3A; static const uint8_t _TIME_LIMIT_A = 0x3B; static const uint8_t _TIME_LATENCY_A = 0x3C; static const uint8_t _TIME_WINDOW_A = 0x3D; //Magnetic sensor register definition static const uint8_t _CRA_REG_M = 0x00; static const uint8_t _CRB_REG_M = 0x01; static const uint8_t _MR_REG_M = 0x02; static const uint8_t _OUT_X_H_M = 0x03; static const uint8_t _OUT_X_L_M = 0x04; static const uint8_t _OUT_Z_H_M = 0x05; static const uint8_t _OUT_Z_L_M = 0x06; static const uint8_t _OUT_Y_H_M = 0x07; static const uint8_t _OUT_Y_L_M = 0x08; static const uint8_t _SR_REG_M = 0x09; static const uint8_t _IRA_REG_M = 0x0A; static const uint8_t _IRB_REG_M = 0x0B; static const uint8_t _IRC_REG_M = 0x0C; static const uint8_t _TEMP_OUT_H_M = 0x31; static const uint8_t _TEMP_OUT_L_M = 0x32; //Driver function definition bool LSM303_Init(LSM303 *device, I2C_HandleTypeDef *i2cHandler) { if(!device || !i2cHandler)return false; device->i2cHandler = i2cHandler; device->opMode = CONTINUOUS_CONVERSION; device->enableTempSensor = false; return true; } bool LSM303_EnableTemperatureSensor(LSM303 *device, bool enable) { if(!device) return false; device->enableTempSensor = enable; return true; } bool LSM303_SetMagneticSensorOperationMode(LSM303 *device, OperationMode opMode) { if(!device) return false; device->opMode = opMode; return true; } bool LSM303_ApplyConfig(LSM303 *device) { if(!device) return false; //We apply the temperature config uint8_t data = 0; if(!LSM303_ReadRegister(device, CRA_REG_M, &data)) return false; if(device->enableTempSensor) { if(!LSM303_WriteRegister(device, CRA_REG_M, data | (1 << 7))) return false; } else { if(!LSM303_WriteRegister(device, CRA_REG_M, data & ~(1 << 7))) return false; } //We apply the operation mode if(!LSM303_WriteRegister(device, MR_REG_M, device->opMode)) return false; return true; } bool LSM303_GetDeviceID(LSM303 *device, uint8_t id[3]) { if(!device) return false; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(device->i2cHandler, LMS303DLHC_COMP_ADDR, (uint8_t *)&_IRA_REG_M, 1, HAL_MAX_DELAY); if(status != HAL_OK) return false; return HAL_I2C_Master_Receive(device->i2cHandler, LMS303DLHC_COMP_ADDR, id, 3, HAL_MAX_DELAY) == HAL_OK ? true : false; } bool LSM303_GetTemperature(LSM303 *device, float *temperature, int16_t *rawValue) { if(!device) return false; uint8_t data[2]; int16_t orderedData; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(device->i2cHandler, LMS303DLHC_COMP_ADDR, (uint8_t *)&_TEMP_OUT_H_M, 1, HAL_MAX_DELAY); if(status != HAL_OK) return false; status = HAL_I2C_Master_Receive(device->i2cHandler, LMS303DLHC_COMP_ADDR, data, 2, HAL_MAX_DELAY); if(status != HAL_OK) return false; //We switch the bytes... ((uint8_t *)&orderedData)[0] = data[1]; ((uint8_t *)&orderedData)[1] = data[0]; if(rawValue) *rawValue = orderedData; if(temperature) *temperature = (float)orderedData / 256; return true; } bool LSM303_GetMagneticFieldData(LSM303 *device, int16_t *xAxis, int16_t *yAxis, int16_t *zAxis) { if(!device) return false; uint8_t data[6]; int16_t x,y,z; HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(device->i2cHandler, LMS303DLHC_COMP_ADDR, (uint8_t *)&_OUT_X_H_M, 1, HAL_MAX_DELAY); if(status != HAL_OK) return false; //We now read all six registers status = HAL_I2C_Master_Receive(device->i2cHandler, LMS303DLHC_COMP_ADDR, data, 8, HAL_MAX_DELAY); if(status != HAL_OK) return false; //We switch the bytes... ((uint8_t *)&x)[0] = data[1]; ((uint8_t *)&x)[1] = data[0]; ((uint8_t *)&z)[0] = data[3]; ((uint8_t *)&z)[1] = data[2]; ((uint8_t *)&y)[0] = data[5]; ((uint8_t *)&y)[1] = data[4]; if(xAxis) *xAxis = x; if(yAxis) *yAxis = y; if(zAxis) *zAxis = z; return true; } bool LSM303_ReadRegister(LSM303 *device, uint8_t registerAddr, uint8_t *data) { HAL_StatusTypeDef status = HAL_I2C_Master_Transmit(device->i2cHandler, LMS303DLHC_COMP_ADDR, ®isterAddr, 1, HAL_MAX_DELAY); if(status != HAL_OK) return false; return HAL_I2C_Master_Receive(device->i2cHandler, LMS303DLHC_COMP_ADDR, data, 1, HAL_MAX_DELAY) == HAL_OK ? true : false; } bool LSM303_WriteRegister(LSM303 *device, uint8_t registerAddr, uint8_t data) { uint8_t regAndData[] = {registerAddr, data}; return HAL_I2C_Master_Transmit(device->i2cHandler, LMS303DLHC_COMP_ADDR, regAndData, 2, HAL_MAX_DELAY) == HAL_OK ? true : false; }