208 lines
5.7 KiB
C
208 lines
5.7 KiB
C
/*
|
|
* 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;
|
|
}
|