초보의 아웅다웅 설계하기/STM32

LSM6DSL, LIS2MDL, LPS22HB

로망와니 2019. 3. 1. 00:52

가속, 자이로, 온도, 압감지, 마그넷 센서

LSM6DSL, LIS2MDL, LPS22HB

소스와 통신하는 부분을 ST에서 제공하는 프로그램에서 발췌했더니 비효율적으로 되어있습니다.

데이터시트를 보고 최적화와 함께 함수들을 만들어 써야합니다. 


void main(void)

{

ACCGyroAxis_TypeDef ACCAxis, GyroAxis;

MagnetAxis_TypeDef MagnetAxis;

float fPress, ftemperature;

float fBatt;

uint16_t Batt_Percent;


LSM6DSL_ACCGyroInit();

LIS2MDL_MagnetInit();

LPS22HB_TempPreInit();


LSM6DSL_ACCGyroEnable();

LIS2MDL_MagnetEnable();

LPS22HB_TempPreEnable();


LSM6DSL_ACCGyroSetting();

LIS2MDL_MagnetSetting();

while(1)

{

MeasurementSensorData(5, &ACCAxis, &GyroAxis, &MagnetAxis, &fPress, &ftemperature, &fBatt, &Batt_Percent);

}

}



/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_2G   0.061  /**< Sensitivity value for 2 g full scale [mg/LSB] */

#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_4G   0.122  /**< Sensitivity value for 4 g full scale [mg/LSB] */

#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_8G   0.244  /**< Sensitivity value for 8 g full scale [mg/LSB] */

#define LSM6DSL_ACC_SENSITIVITY_FOR_FS_16G  0.488  /**< Sensitivity value for 16 g full scale [mg/LSB] */


#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_125DPS   04.375  /**< Sensitivity value for 125 dps full scale [mdps/LSB] */

#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_245DPS   08.750  /**< Sensitivity value for 245 dps full scale [mdps/LSB] */

#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_500DPS   17.500  /**< Sensitivity value for 500 dps full scale [mdps/LSB] */

#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_1000DPS  35.000  /**< Sensitivity value for 1000 dps full scale [mdps/LSB] */

#define LSM6DSL_GYRO_SENSITIVITY_FOR_FS_2000DPS  70.000  /**< Sensitivity value for 2000 dps full scale [mdps/LSB] */


#define LSM6DSL_ACC_SENSITIVITY LSM6DSL_ACC_SENSITIVITY_FOR_FS_2G

#define LSM6DSL_GYRO_SENSITIVITY LSM6DSL_GYRO_SENSITIVITY_FOR_FS_2000DPS


typedef enum {

 eModeACC = 0,  

 eModeGyro,  

} eModeACCGyro_TypeDef;


typedef struct {

int32_t ACCGyro_X;

int32_t ACCGyro_Y;

int32_t ACCGyro_Z;

}ACCGyroAxis_TypeDef;


//#define LSM6DSL_RESERVED 0x00

#define LSM6DSL_FUNC_CFG_ACCESS 0x01 //Embedded functions

//#define LSM6DSL_RESERVED 0x02

//#define LSM6DSL_RESERVED 0x03

#define LSM6DSL_SENSOR_SYNC_TIME_FRAME 0x04 //r/w

#define LSM6DSL_SENSOR_SYNC_RES_RATIO 0x05 //r/w

#define LSM6DSL_FIFO_CTRL1 0x06 //r/w

#define LSM6DSL_FIFO_CTRL2 0x07 //r/w

#define LSM6DSL_FIFO_CTRL3 0x08 //r/w

#define LSM6DSL_FIFO_CTRL4 0x09 //r/w

#define LSM6DSL_FIFO_CTRL5 0x0A //r/w

#define LSM6DSL_DRDY_PULSE_CFG_G 0x0B //r/w

//#define LSM6DSL_RESERVED 0x0C

#define LSM6DSL_INT1_CTRL 0x0D //r/w INT1 pin control

#define LSM6DSL_INT2_CTRL 0x0E //r/w INT2 pin control

#define LSM6DSL_WHO_AM_I 0x0F //r Who I am ID

#define LSM6DSL_CTRL1_XL 0x10 //r/w

#define LSM6DSL_CTRL2_G 0x11 //r/w

#define LSM6DSL_CTRL3_C 0x12 //r/w

#define LSM6DSL_CTRL4_C 0x13 //r/w

#define LSM6DSL_CTRL5_C 0x14 //r/w

#define LSM6DSL_CTRL6_C 0x15 //r/w

#define LSM6DSL_CTRL7_G 0x16 //r/w

#define LSM6DSL_CTRL8_XL 0x17 //r/w

#define LSM6DSL_CTRL9_XL 0x18 //r/w

#define LSM6DSL_CTRL10_C 0x19 //r/w

#define LSM6DSL_MASTER_CONFIG 0x1A //r/w

#define LSM6DSL_WAKE_UP_SRC 0x1B //r

#define LSM6DSL_TAP_SRC 0x1C //r  Interrupt registers

#define LSM6DSL_D6D_SRC 0x1D //r  

#define LSM6DSL_STATUS_REG 0x1E //r  

//#define LSM6DSL_RESERVED 0x1F

#define LSM6DSL_OUT_TEMP_L 0x20 //r   Temperature output

#define LSM6DSL_OUT_TEMP_H 0x21 //r   data registers

#define LSM6DSL_OUTX_L_G 0x22 //r   GYRO

#define LSM6DSL_OUTX_H_G 0x23 //r  

#define LSM6DSL_OUTY_L_G 0x24 //r  

#define LSM6DSL_OUTY_H_G 0x25 //r  

#define LSM6DSL_OUTZ_L_G 0x26 //r  

#define LSM6DSL_OUTZ_H_G 0x27 //r  

#define LSM6DSL_OUTX_L_XL 0x28 //r   ACC

#define LSM6DSL_OUTX_H_XL 0x29 //r  

#define LSM6DSL_OUTY_L_XL 0x2A //r  

#define LSM6DSL_OUTY_H_XL 0x2B //r  

#define LSM6DSL_OUTZ_L_XL 0x2C //r  

#define LSM6DSL_OUTZ_H_XL 0x2D //r  

#define LSM6DSL_SENSORHUB1_REG 0x2E //r  

#define LSM6DSL_SENSORHUB2_REG 0x2F //r  

#define LSM6DSL_SENSORHUB3_REG 0x30 //r  

#define LSM6DSL_SENSORHUB4_REG 0x31 //r  

#define LSM6DSL_SENSORHUB5_REG 0x32 //r  

#define LSM6DSL_SENSORHUB6_REG 0x33 //r  

#define LSM6DSL_SENSORHUB7_REG 0x34 //r  

#define LSM6DSL_SENSORHUB8_REG 0x35 //r  

#define LSM6DSL_SENSORHUB9_REG 0x36 //r  

#define LSM6DSL_SENSORHUB10_REG 0x37 //r  

#define LSM6DSL_SENSORHUB11_REG 0x38 //r  

#define LSM6DSL_SENSORHUB12_REG 0x39 //r  

#define LSM6DSL_FIFO_STATUS1 0x3A //r  

#define LSM6DSL_FIFO_STATUS2 0x3B //r  

#define LSM6DSL_FIFO_STATUS3 0x3C //r  

#define LSM6DSL_FIFO_STATUS4 0x3D //r  

#define LSM6DSL_FIFO_DATA_OUT_L 0x3E //r   FIFO data output

#define LSM6DSL_FIFO_DATA_OUT_H 0x3F //r  

#define LSM6DSL_TIMESTAMP0_REG 0x40 //r  

#define LSM6DSL_TIMESTAMP1_REG 0x41 //r  

#define LSM6DSL_TIMESTAMP2_REG 0x42 //r/w  

//#define LSM6DSL_RESERVED 0x43 ~ 0x48

#define LSM6DSL_STEP_TIMESTAMP_L 0x49 //r   Step counter

#define LSM6DSL_STEP_TIMESTAMP_H 0x4A //r   timestamp registers

#define LSM6DSL_STEP_COUNTER_L 0x4B //r   Step counte0xoutput

#define LSM6DSL_STEP_COUNTER_H 0x4C //r   registers

#define LSM6DSL_SENSORHUB13_REG 0x4D //r  

#define LSM6DSL_SENSORHUB14_REG 0x4E //r  

#define LSM6DSL_SENSORHUB15_REG 0x4F //r  

#define LSM6DSL_SENSORHUB16_REG 0x50 //r  

#define LSM6DSL_SENSORHUB17_REG 0x51 //r  

#define LSM6DSL_SENSORHUB18_REG 0x52 //r  

#define LSM6DSL_FUNC_SRC1 0x53 //r  

#define LSM6DSL_FUNC_SRC2 0x54 //r  

#define LSM6DSL_WRIST_TILT_IA 0x55 //r   Interrupt register

//#define LSM6DSL_RESERVED - 56-57 - 

#define LSM6DSL_TAP_CFG 0x58 //r/w  

#define LSM6DSL_TAP_THS_6D 0x59 //r/w  

#define LSM6DSL_INT_DUR2 0x5A //r/w  

#define LSM6DSL_WAKE_UP_THS 0x5B //r/w  

#define LSM6DSL_WAKE_UP_DU0x0x5C //r/w  

#define LSM6DSL_FREE_FALL 0x5D //r/w  

#define LSM6DSL_MD1_CFG 0x5E //r/w  

#define LSM6DSL_MD2_CFG 0x5F //r/w  

#define LSM6DSL_MASTER_CMD_CODE 0x60 //r/w  

#define LSM6DSL_SENS_SYNC_SPI_ERROR_CODE 0x61 //r/w 

//#define LSM6DSL_RESERVED - 62-65 - Reserved

#define LSM6DSL_OUT_MAG_RAW_X_L 0x66 //r  

#define LSM6DSL_OUT_MAG_RAW_X_H 0x67 //r  

#define LSM6DSL_OUT_MAG_RAW_Y_L 0x68 //r  

#define LSM6DSL_OUT_MAG_RAW_Y_H 0x69 //r  

#define LSM6DSL_OUT_MAG_RAW_Z_L 0x6A //r  

#define LSM6DSL_OUT_MAG_RAW_Z_H 0x6B //r  

//#define LSM6DSL_RESERVED - 6C-72 - 

#define LSM6DSL_X_OFS_US0x0x73 //r/w  

#define LSM6DSL_Y_OFS_US0x0x74 //r/w  

#define LSM6DSL_Z_OFS_US0x0x75 //r/w  

//#define LSM6DSL_RESERVED - 76-7F -



/* Private macro ------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes ------------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

extern void UART1_printf(const char *fmt,...);

ACCGyroAxis_TypeDef gstACCAxis;

ACCGyroAxis_TypeDef gstGyroAxis;



/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LSM6DSL_ACCGyroInit(void)

{

uint8_t Data[10];


Data[0] = 0x0C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

Data[0] = 0x00;

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_WHO_AM_I, Data, 1);

Data[0] = 0x6A;

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

Data[0] = 0x0C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

Data[0] = 0x4C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_FIFO_CTRL5, Data, 1);

Data[0] = 0x00;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_FIFO_CTRL5, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL1_XL, Data, 1);

Data[0] = 0x00;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL1_XL, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL1_XL, Data, 1);

Data[0] = 0x00;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL1_XL, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL4_C, Data, 1);

Data[0] = 0x04;

SPI2_1Wire_Write(CS_LSM6DSL,LSM6DSL_CTRL4_C, Data, 1);

Data[0] = 0x00;

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_WHO_AM_I, Data, 1);

Data[0] = 0x6A;

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

Data[0] = 0x4C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

Data[0] = 0x4C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL3_C, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_FIFO_CTRL5, Data, 1);

Data[0] = 0x00;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_FIFO_CTRL5, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL2_G, Data, 1);

Data[0] = 0x0C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL2_G, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL2_G, Data, 1);

Data[0] = 0x0C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL2_G, Data, 1);

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL4_C, Data, 1);

Data[0] = 0x04;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL4_C, Data, 1);

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

<- \ ACC + / ACC-

Side

Right - Left +

*******************************************************************************/

void LSM6DSL_ACCGyroEnable(void)

{

uint8_t Data[10], ACCGyroLoop;

Data[0] = 0x01;

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL1_XL, Data, 1);

Data[0] = 0x40;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL1_XL, Data, 1);

Data[0] = 0x0A;

SPI2_1Wire_Read(CS_LSM6DSL, LSM6DSL_CTRL2_G, Data, 1);

Data[0] = 0x4C;

SPI2_1Wire_Write(CS_LSM6DSL, LSM6DSL_CTRL2_G, Data, 1);

delay_ms(100);

ACCGyroAxis_TypeDef ACCAxis, GyroAxis;

LSM6DSL_ACCGyroGet(&gstACCAxis, &gstGyroAxis);

for(ACCGyroLoop = 0; ACCGyroLoop < 10; ACCGyroLoop++){

LSM6DSL_ACCGyroGet(&ACCAxis, &GyroAxis);

gstACCAxis.ACCGyro_X = (gstACCAxis.ACCGyro_X + ACCAxis.ACCGyro_X)/2;

gstACCAxis.ACCGyro_Y = (gstACCAxis.ACCGyro_Y + ACCAxis.ACCGyro_Y)/2;

gstACCAxis.ACCGyro_Z = (gstACCAxis.ACCGyro_Z + ACCAxis.ACCGyro_Z)/2;

gstGyroAxis.ACCGyro_X = (gstGyroAxis.ACCGyro_X + GyroAxis.ACCGyro_X)/2;

gstGyroAxis.ACCGyro_Y = (gstGyroAxis.ACCGyro_Y + GyroAxis.ACCGyro_Y)/2;

gstGyroAxis.ACCGyro_Z = (gstGyroAxis.ACCGyro_Z + GyroAxis.ACCGyro_Z)/2;

delay_ms(1);

}

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LSM6DSL_ACCGyroSetting(void)

{

uint8_t Data[10];


//ODR 6.6kHz   

Data[0] = 0x0A;

SPI2_1Wire_Read(CS_LSM6DSL, 0x10, Data, 1);

Data[0] = 0xA0;

SPI2_1Wire_Write(CS_LSM6DSL, 0x10, Data, 1);

//FS 4g

Data[0] = 0xA0;

SPI2_1Wire_Read(CS_LSM6DSL, 0x10, Data, 1);

Data[0] = 0xA8;

SPI2_1Wire_Write(CS_LSM6DSL, 0x10, Data, 1);

//ODR/2 low pass filtered sent to composite filter

Data[0] = 0xA8;

SPI2_1Wire_Read(CS_LSM6DSL, 0x17, Data, 1);

Data[0] &= ~0x80;//LSM6DSL_ACC_GYRO_IN_COMP_MASK;

  Data[0] |= 0x00;//LSM6DSL_ACC_GYRO_IN_ODR_DIV_2;

SPI2_1Wire_Write(CS_LSM6DSL, 0x17, Data, 1);

//Enable LPF2 filter in composite filter block

Data[0] = 0x60;

SPI2_1Wire_Read(CS_LSM6DSL, 0x17, Data, 1);

Data[0] &= ~0x80;//LSM6DSL_ACC_GYRO_LPF2_XL_MASK;

  Data[0] |= 0x80;//LSM6DSL_ACC_GYRO_LPF2_XL_ENABLE;

SPI2_1Wire_Write(CS_LSM6DSL, 0x17, Data, 1);

//Low pass filter @ ODR/400

Data[0] = 0xE0;

SPI2_1Wire_Read(CS_LSM6DSL, 0x17, Data, 1);

Data[0] &= ~0x60;//LSM6DSL_ACC_GYRO_HPCF_XL_MASK;

  Data[0] |= 0x60;//LSM6DSL_ACC_GYRO_HPCF_XL_DIV400;

SPI2_1Wire_Write(CS_LSM6DSL, 0x17, Data, 1);

//ACC Read

Data[0] = 0x00;

SPI2_1Wire_Read(CS_LSM6DSL, 0x10, Data, 1);

//Set LSB to 0 >> Analog filter 1500Hz

Data[0] &= 0xFE;

SPI2_1Wire_Write(CS_LSM6DSL, 0x10, Data, 1);

// Initialize settings for 6-axis MEMS Gyroscope 

// FS 2000dps */

// ODR 416Hz */

// LPF1 FTYPE set to 10b 

Data[0] = 0xA8;

SPI2_1Wire_Read(CS_LSM6DSL, 0x15, Data, 1);

Data[0] &= ~0x03;//LSM6DSL_ACC_GYRO_FTYPE_MASK   

  Data[0] |= 0x01;//LSM6DSL_ACC_GYRO_LP_G_NARROW 

SPI2_1Wire_Write(CS_LSM6DSL, 0x15, Data, 1);

//Gyroscope settings: full scale 2000dps, ODR 416Hz

Data[0] = 0x6C;

SPI2_1Wire_Write(CS_LSM6DSL, 0x11, Data, 1);

}

/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LSM6DSL_ACCGyro(uint8_t *pRawdata, ACCGyroAxis_TypeDef *ACCGyroAxis, eModeACCGyro_TypeDef chMode)

{

short int ACCGyroTemp;

if(chMode == eModeACC){

ACCGyroTemp = ((((uint16_t)pRawdata[1]) << 8) + (uint16_t)pRawdata[0]);

ACCGyroAxis->ACCGyro_X = (ACCGyroTemp * LSM6DSL_ACC_SENSITIVITY);

ACCGyroTemp = ((((uint16_t)pRawdata[3]) << 8) + (uint16_t)pRawdata[2]);

ACCGyroAxis->ACCGyro_Y = (ACCGyroTemp * LSM6DSL_ACC_SENSITIVITY);

ACCGyroTemp = ((((uint16_t)pRawdata[5]) << 8) + (uint16_t)pRawdata[4]);

ACCGyroAxis->ACCGyro_Z = (ACCGyroTemp * LSM6DSL_ACC_SENSITIVITY);

}

else if(chMode == eModeGyro){

ACCGyroTemp = ((((uint16_t)pRawdata[1]) << 8) + (uint16_t)pRawdata[0]);

ACCGyroAxis->ACCGyro_X = (ACCGyroTemp * LSM6DSL_GYRO_SENSITIVITY);

ACCGyroTemp = ((((uint16_t)pRawdata[3]) << 8) + (uint16_t)pRawdata[2]);

ACCGyroAxis->ACCGyro_Y = (ACCGyroTemp * LSM6DSL_GYRO_SENSITIVITY);

ACCGyroTemp = ((((uint16_t)pRawdata[5]) << 8) + (uint16_t)pRawdata[4]);

ACCGyroAxis->ACCGyro_Z = (ACCGyroTemp * LSM6DSL_GYRO_SENSITIVITY);

}

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LSM6DSL_RawData(uint8_t *pAddr, uint8_t *pRawData, uint8_t chLen)

{

uint8_t SpiLoop;

for(SpiLoop = 0; SpiLoop < chLen; SpiLoop++){

// UART1_printf("%02X, %02X, %02X \r\n", CS_LSM6DSL, pAddr[SpiLoop], pRawData[SpiLoop]);

SPI2_1Wire_Read(CS_LSM6DSL, pAddr[SpiLoop], &pRawData[SpiLoop], 1 );

}

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LSM6DSL_ACCGyroGet(ACCGyroAxis_TypeDef *ACCAxis, ACCGyroAxis_TypeDef *GyroAxis)

{

const uint8_t Data_ACCGyro[15] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFE};

uint8_t Addr_ACCGyro[15] = \

{LSM6DSL_OUTX_L_XL, LSM6DSL_OUTX_H_XL, LSM6DSL_OUTY_L_XL, LSM6DSL_OUTY_H_XL, LSM6DSL_OUTZ_L_XL, LSM6DSL_OUTZ_H_XL\

, LSM6DSL_CTRL1_XL,\

LSM6DSL_OUTX_L_G, LSM6DSL_OUTX_H_G, LSM6DSL_OUTY_L_G, LSM6DSL_OUTY_H_G, LSM6DSL_OUTZ_L_G, LSM6DSL_OUTZ_H_G\

, LSM6DSL_CTRL2_G, LSM6DSL_CTRL2_G};

uint8_t Data[15] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0xFE};

uint8_t pData[6];


memcpy(Data, Data_ACCGyro, 15);

LSM6DSL_RawData(Addr_ACCGyro, Data, 15);//0~5, 7~12

memcpy(pData, Data, 6);

LSM6DSL_ACCGyro(pData, ACCAxis, eModeACC);

memcpy(pData, Data+7, 6);

LSM6DSL_ACCGyro(pData, GyroAxis, eModeGyro);

}


/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

typedef struct {

int32_t Mag_X;

int32_t Mag_Y;

int32_t Mag_Z;

}MagnetAxis_TypeDef;


//#define LIS2MDL_Reserved 00 - 44 Reserved

#define LIS2MDL_OFFSET_X_REG_L 0x45 //r/w  Hard-iron registers

#define LIS2MDL_OFFSET_X_REG_H 0x46 //r/w 

#define LIS2MDL_OFFSET_Y_REG_L 0x47 //r/w 

#define LIS2MDL_OFFSET_Y_REG_H 0x48 //r/w 

#define LIS2MDL_OFFSET_Z_REG_L 0x49 //r/w 

#define LIS2MDL_OFFSET_Z_REG_H 0x4A //r/w 

//#define LIS2MDL_RESERVED 4B-4C Reserved

#define LIS2MDL_WHO_AM_I 0x4F //r 

//#define LIS2MDL_RESERVED 50-5F Reserved

#define LIS2MDL_CFG_REG_A 0x60 //r/w  Configuration

#define LIS2MDL_CFG_REG_B 0x61 //r/w 

#define LIS2MDL_CFG_REG_C 0x62 //r/w 

#define LIS2MDL_INT_CRTL_REG 0x63 //r/w  configuration registers

#define LIS2MDL_INT_SOURCE_REG 0x64 //r

#define LIS2MDL_INT_THS_L_REG 0x65 //r/w 

#define LIS2MDL_INT_THS_H_REG 0x66 //r/w 

#define LIS2MDL_STATUS_REG 0x67 //r

#define LIS2MDL_OUTX_L_REG 0x68 //r  Output registers

#define LIS2MDL_OUTX_H_REG 0x69 //r 

#define LIS2MDL_OUTY_L_REG 0x6A //r 

#define LIS2MDL_OUTY_H_REG 0x6B //r 

#define LIS2MDL_OUTZ_L_REG 0x6C //r 

#define LIS2MDL_OUTZ_H_REG 0x6D //r 

#define LIS2MDL_TEMP_OUT_L_REG 0x6E //r  Temperature sensor

#define LIS2MDL_TEMP_OUT_H_REG 0x6F //r 


/* Private macro ------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes ------------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

extern void UART1_printf(const char *fmt,...);

MagnetAxis_TypeDef gStMagnetAxis;


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LIS2MDL_MagnetInit(void)

{

uint8_t Data[10];


Data[0] = 0x00;

SPI2_1Wire_Read(CS_LIS2MDL, LIS2MDL_WHO_AM_I, Data, 1);

Data[0] = 0x40;

SPI2_1Wire_Read(CS_LIS2MDL, LIS2MDL_CFG_REG_A, Data, 1);//reboot memory content

Data[0] = 0x0F;

SPI2_1Wire_Write(CS_LIS2MDL, LIS2MDL_CFG_REG_A, Data, 1);//Output data rate configuration - 50Hz

SPI2_1Wire_Read(CS_LIS2MDL, LIS2MDL_CFG_REG_C, Data, 1);

Data[0] = 0x10;

SPI2_1Wire_Write(CS_LIS2MDL, LIS2MDL_CFG_REG_C, Data, 1);// reading of incorrect data is avoided when the user reads asynchronously

SPI2_1Wire_Read(CS_LIS2MDL, LIS2MDL_CFG_REG_A, Data, 1);

Data[0] = 0x0F;

SPI2_1Wire_Write(CS_LIS2MDL, LIS2MDL_CFG_REG_A, Data, 1);

SPI2_1Wire_Read(CS_LIS2MDL, LIS2MDL_CFG_REG_C, Data, 1);

Data[0] = 0x10;

SPI2_1Wire_Write(CS_LIS2MDL, LIS2MDL_CFG_REG_C, Data, 1);

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

1. Write CFG_REG_A = 80h // Enable temperature compensation

//Mag = 10 Hz (high-resolution and continuous mode)

2. Write CFG_REG_C = 01h // Mag data-ready interrupt enable

*******************************************************************************/

void LIS2MDL_MagnetEnable(void)

{

uint8_t Data[10];


Data[0] = 0x0A;

SPI2_1Wire_Read(CS_LIS2MDL, LIS2MDL_CFG_REG_A, Data, 1);

Data[0] = 0x0C;

SPI2_1Wire_Write(CS_LIS2MDL, LIS2MDL_CFG_REG_A, Data, 1);//100Hz

}



/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

Initialize settings for Magnetometer settings 

(By default after reset is in in idle mode) 

*******************************************************************************/

void LIS2MDL_MagnetSetting(void)

{

uint8_t Data[10];


Data[0] = 0x8C;

SPI2_1Wire_Write(CS_LIS2MDL, LIS2MDL_CFG_REG_A, Data, 1);

Data[0] = 0x02;

SPI2_1Wire_Write(CS_LIS2MDL, LIS2MDL_CFG_REG_B, Data, 1);

}

/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LIS2MDL_Magnet(uint8_t *pRawdata, MagnetAxis_TypeDef *MagnetAxis, float fSensitivity)

{

short int MagnetTemp;

MagnetTemp = (((uint16_t)pRawdata[1]) << 8) + (uint16_t)pRawdata[0];

MagnetAxis->Mag_X = (MagnetTemp * fSensitivity);

MagnetTemp = (((uint16_t)pRawdata[3]) << 8) + (uint16_t)pRawdata[2];

MagnetAxis->Mag_Y  = (MagnetTemp * fSensitivity);

MagnetTemp = (((uint16_t)pRawdata[5]) << 8) + (uint16_t)pRawdata[4];

MagnetAxis->Mag_Z  = (MagnetTemp * fSensitivity);

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LIS2MDL_RawData(uint8_t *pAddr, uint8_t *pRawData, uint8_t chLen)

{

uint8_t SpiLoop;

for(SpiLoop = 0; SpiLoop < chLen; SpiLoop++){

// UART1_printf("%02X, %02X, %02X \r\n", CS_LIS2MDL, pAddr[SpiLoop], pRawData[SpiLoop]);

SPI2_1Wire_Read(CS_LIS2MDL, pAddr[SpiLoop], &pRawData[SpiLoop], 1 );

}

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LIS2MDL_MagnetGet(MagnetAxis_TypeDef *MagnetAxis)

{

uint8_t Addr_Magnet[6] = {0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D};

uint8_t Data[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};


int16_t *pRawData;

float Sensitivity = 1.5f;

LIS2MDL_RawData(Addr_Magnet, Data, 6);

LIS2MDL_Magnet(Data, MagnetAxis, Sensitivity);

}


/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

//#define LPS22HB_Reserved 0x00 - 0A - Reserved

#define LPS22HB_INTERRUPT_CFG 0x0B //r/w Interrupt register

#define LPS22HB_THS_P_L 0x0C //r/w threshold registers

#define LPS22HB_THS_P_H 0x0D //r/w

//#define LPS22HB_Reserved 0E - Reserved

#define LPS22HB_WHO_AM_I 0x0F //r Who am I

#define LPS22HB_CTRL_REG1 0x10 //r/w

#define LPS22HB_CTRL_REG2 0x11 //r/w Control registers

#define LPS22HB_CTRL_REG3 0x12 //r/w

//#define LPS22HB_Reserved 13 - Reserved

#define LPS22HB_FIFO_CTRL 0x14 //r/w FIFO configuration register

#define LPS22HB_REF_P_XL 0x15 //r/w

#define LPS22HB_REF_P_L 0x16 //r/w Reference pressure registers

#define LPS22HB_REF_P_H 0x17 //r/w

#define LPS22HB_RPDS_L 0x18 //r/w offset registers

#define LPS22HB_RPDS_H 0x19 //r/w

#define LPS22HB_RES_CONF 0x1A //r/w Resolution register

//#define LPS22HB_Reserved 1B - 24 - Reserved

#define LPS22HB_INT_SOURCE 0x25 //r Interrupt register

#define LPS22HB_FIFO_STATUS 0x26 //r FIFO status register

#define LPS22HB_STATUS 0x27 //r Status register

#define LPS22HB_PRESS_OUT_XL 0x28 //r

#define LPS22HB_PRESS_OUT_L 0x29 //r Pressure output registers

#define LPS22HB_PRESS_OUT_H 0x2A //r

#define LPS22HB_TEMP_OUT_L 0x2B //r Temperature output registers

#define LPS22HB_TEMP_OUT_H 0x2C //r

//#define LPS22HB_Reserved 2D - 32 - Reserved

#define LPS22HB_LPFP_RES 0x33 //r Filte0xreset register


/* Private macro ------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes ------------------------------------------------*/

/* Private functions ---------------------------------------------------------*/


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LPS22HB_TempPreInit(void)

{

uint8_t Data[10];


Data[0] = 0x01;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG2, Data, 1);

Data[0] = 0xFC;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG2, Data, 1);

Data[0] = 0x01;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

Data[0] = 0x01;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

Data[0] = 0x00;

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_WHO_AM_I, Data, 1);


Data[0] = 0xB1;

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_RES_CONF, Data, 1);


Data[0] = 0x01;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_RES_CONF, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

Data[0] = 0x01;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

Data[0] = 0x01;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

Data[0] = 0x01;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);


Data[0] = 0x03;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG2, Data, 1);


Data[0] = 0x00;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG2, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);


Data[0] = 0x03;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG2, Data, 1);


Data[0] = 0xF8;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG2, Data, 1);

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LPS22HB_TempPreEnable(void)

{

uint8_t Data[10];

Data[0] = 0x0A;

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

Data[0] = 0x33;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);


Data[0] = 0x0A;

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);


Data[0] = 0x33;

SPI2_1Wire_Write(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

SPI2_1Wire_Read(CS_LPS22HB, LPS22HB_CTRL_REG1, Data, 1);

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LPS22HB_Press(uint8_t *pRawdata, float *fPress)

{

int32_t RawPresse, Pout;

  uint32_t Temp = 0;

  uint8_t PressLoop;


  for(PressLoop = 0; PressLoop < 3; PressLoop++){

    Temp |= (((uint32_t)pRawdata[PressLoop]) << (8 * PressLoop));

}


  /* convert the 2's complement 24 bit to 2's complement 32 bit */

  if(Temp & 0x00800000){

    Temp |= 0xFF000000;

}


  RawPresse = ((int32_t)Temp);

Pout = (RawPresse * 100) / 4096;

*fPress = ( float )Pout / 100.0f;

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LPS22HB_Temperature(uint8_t *pRawdata, float *fTemperature)

{

short int TemperatureTemp = 0, Tout = 0;

TemperatureTemp = (((uint16_t)pRawdata[1]) << 8) + (uint16_t)pRawdata[0];

Tout = (TemperatureTemp * 10) / 100;

*fTemperature = (float)Tout / 10.0f;

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LPS22HB_RawData(uint8_t *pAddr, uint8_t *pRawData, uint8_t chLen)

{

uint8_t SpiLoop;

for(SpiLoop = 0; SpiLoop < chLen; SpiLoop++){

// UART1_printf("%02X, %02X, %02X \r\n", CS_LPS22HB, pAddr[SpiLoop], pRawData[SpiLoop]);

SPI2_1Wire_Read(CS_LPS22HB, pAddr[SpiLoop], &pRawData[SpiLoop], 1 );

}

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : None

* Description   : 

*******************************************************************************/

void LPS22HB_TempPressGet(float *fPress, float *ftemperature)

{

uint8_t Addr_Temperature[2] = {0x2B, 0x2C};

uint8_t Addr_Pressure[3] = {0x28, 0x29, 0x2A};

  uint8_t data[3] = {0x4F, 0xFF, 0x00};

LPS22HB_RawData(Addr_Temperature, data, 2);

LPS22HB_Temperature(data, ftemperature);


LPS22HB_RawData(Addr_Pressure, data, 3);

LPS22HB_Press(data, fPress);

}


/*******************************************************************************

* Function Name : 

* Parameters    : None

* Return        : 

* Description   : 

*******************************************************************************/

void MeasurementSensorData(const uint8_t ConvertType,ACCGyroAxis_TypeDef *pACCAxis, ACCGyroAxis_TypeDef *pGyroAxis, MagnetAxis_TypeDef *pMagnetAxis, float *pfPress, float *pftemperature, float *pfBatt, uint16_t *pBatt_Percent)

{

int32_t Tmp;


ACCGyroAxis_TypeDef ACCAxis, GyroAxis;

MagnetAxis_TypeDef MagnetAxis;

float fPress, ftemperature;


/* Measurement */

LSM6DSL_ACCGyroGet(&ACCAxis, &GyroAxis);

LIS2MDL_MagnetGet(&MagnetAxis);

LPS22HB_TempPressGet(pfPress, pftemperature);

*pfBatt = Calculation_VBAT(uhADCxConvertedValue[0], 0);

*pBatt_Percent = Calculation_VBAT_Percent(*pfBatt, MINVOLTAGE, MAXVOLTAGE, TARGETPERCENT);

pMagnetAxis->Mag_X = (int32_t) MagnetAxis.Mag_X;

pMagnetAxis->Mag_Y = (int32_t) MagnetAxis.Mag_Y;

pMagnetAxis->Mag_Z = (int32_t) MagnetAxis.Mag_Z;


if(ConvertType == 1){

Tmp = pACCAxis->ACCGyro_X;

pACCAxis->ACCGyro_X = pACCAxis->ACCGyro_Y;

pACCAxis->ACCGyro_Y = -Tmp;


Tmp = pGyroAxis->ACCGyro_X;

pGyroAxis->ACCGyro_X = pGyroAxis->ACCGyro_Y;

pGyroAxis->ACCGyro_Y = -Tmp;


Tmp = pMagnetAxis->Mag_X;

pMagnetAxis->Mag_X = pMagnetAxis->Mag_Y;

pMagnetAxis->Mag_Y = -Tmp;

}

else if (ConvertType == 2){

}

else if (ConvertType == 3){

pACCAxis->ACCGyro_X = -ACCAxis.ACCGyro_Y;

pACCAxis->ACCGyro_Y = ACCAxis.ACCGyro_X;

pACCAxis->ACCGyro_Z = ACCAxis.ACCGyro_Z;


pGyroAxis->ACCGyro_X = -GyroAxis.ACCGyro_Y; 

pGyroAxis->ACCGyro_Y = GyroAxis.ACCGyro_X;

pGyroAxis->ACCGyro_Z = GyroAxis.ACCGyro_Z;


pMagnetAxis->Mag_X = -MagnetAxis.Mag_Y;

pMagnetAxis->Mag_Y = MagnetAxis.Mag_X;

}

else if (ConvertType == 4){

pACCAxis->ACCGyro_X = -ACCAxis.ACCGyro_X; 

pACCAxis->ACCGyro_Y = -ACCAxis.ACCGyro_Y;


pGyroAxis->ACCGyro_X = -GyroAxis.ACCGyro_X;            

pGyroAxis->ACCGyro_Y = -GyroAxis.ACCGyro_Y;


pMagnetAxis->Mag_X = -MagnetAxis.Mag_X;

pMagnetAxis->Mag_Y = -MagnetAxis.Mag_Y;

}

else if (ConvertType == 5){

pACCAxis->ACCGyro_X = ACCAxis.ACCGyro_X; 

pACCAxis->ACCGyro_Y = ACCAxis.ACCGyro_Y;

pACCAxis->ACCGyro_Z = ACCAxis.ACCGyro_Z;


pGyroAxis->ACCGyro_X = GyroAxis.ACCGyro_X;            

pGyroAxis->ACCGyro_Y = GyroAxis.ACCGyro_Y;

pGyroAxis->ACCGyro_Z = GyroAxis.ACCGyro_Z;

}

}