2023-03-25 02:53 PM
Dear ST Hello,
I am trying to use the ISM330DLC 3D accelerometer and gyroscope with the stm32F329Discovery board and I am facing some problems when I want to read and write all the registers every 10 ms ISR period.
I want to try to change the registers every period without compiling in changing the code each time. I am doing this to have to calibrate the filters in real time.
To do so I am defining all the registers in a header file. here is an example of the status register.
#define ISM330DLC_STATUS_REG 0x1EU
typedef volatile union
{
uint8_t All;
struct
{
uint8_t XLDA :1; //Accelerometer new data available
uint8_t GDA :1; //Gyroscope new data available
uint8_t TDA :1; //Temperature new data available
uint8_t Reserved :5;
} ISM330DLC_RegBits;
} Tun_Status_Reg;
I am doing the same thing to all the registers and I am defining a union (buffer & struct) for all the ISM330DLC registers.
typedef union
{
struct
{
uint8_t Reserved1; //RESERVED
Tun_Runc_Cfg_Access FUNC_CFG_ACCESS; //FUNC_CFG_ACCESS
uint8_t Reserved2; //RESERVED
uint8_t Reserved3; //RESERVED
...
uint8_t Reserved9; //RESERVED
} ISM330DLC_Reg_Struct;
uint8_t ISM330DLC_Reg_Tab[ISM330DLC_MAX_BUFFER_REG];
} ISM330DLC_iDriver_Description;
I stored in an array of structures the type (RW) and the address of each register
Reg_Type_Address IMS330DLC_Reg_Type_Adr [] =
{ //adr //Type //R/W
{.adr=0x00, .type=0xFF}, //- //FF Reserved RESERVED
{.adr=0x01, .type=0x03}, //r/w //0x02 Read FUNC_CFG_ACCESS
{.adr=0x02, .type=0xFF}, //- //0x03 Write RESERVED
{.adr=0x03, .type=0xFF}, //- RESERVED
{.adr=0x04, .type=0x03}, //r/w ENSOR_SYNC_TIME_FRAME
{.adr=0x05, .type=0x03}, //r/w SENSOR_SYNC_RES_RATIO
{.adr=0x06, .type=0x03}, //r/w FIFO_CTRL1
{.adr=0x07, .type=0x03}, //r/w FIFO_CTRL2
...
{.adr=0x6F, .type=0x03}, //r/w INT_OIS
{.adr=0x70, .type=0x03}, //r/w CTRL1_OIS
{.adr=0x71, .type=0x03}, //r/w CTRL2_OIS
{.adr=0x72, .type=0x03}, //r/w CTRL3_OIS
{.adr=0x73, .type=0x03}, //r/w X_OFS_USR
{.adr=0x74, .type=0x03}, //r/w Y_OFS_USR
{.adr=0x75, .type=0x03}, //r/w Z_OFS_USR
{.adr=0x7F, .type=0xFF}, //- RESERVED
};
I have two functions the first one is for init and the second is the task:
The init just fills up the structure with the values to be sent to the Gryro in the init phase.
the BSP_ISM330DLC_ReadWrite_Reg will be called each 10ms and read all the registers and write if any register is manually updated in the real-time watch expression.
uint16_t BSP_ISM330DLC_ReadWrite_Reg(ISM330DLC_iDriver_Description *GyroAccDriverReg, uint16_t Num)
{
uint16_t index;
uint16_t sizeofBuffer;
sizeofBuffer = 40;//sizeof(GyroAccDriverReg->ISM330DLC_Reg_Tab)/sizeof(GyroAccDriverReg->ISM330DLC_Reg_Tab[0]);
if(GyroAcc->ReadID() == GyroAccDriverReg->ISM330DLC_Reg_Struct.WHO_AM_I)
{
for (index = 0; index < sizeofBuffer ; index++)
{
Debugvariable.loop_counter++;
if (0xFF != IMS330DLC_Reg_Type_Adr[index].type)
{
//check if any bit has been changed
if (u8_ISM330DLC_Reg[index] != GyroAccDriverReg->ISM330DLC_Reg_Tab[index])
{
//bit has been changed in the driver register updated it
ISM330DLC_Update_Regiter_Flag = 1;
}
//loop through the buffer and read write if necessary
if (0x02 == IMS330DLC_Reg_Type_Adr[index].type)
{
//read
Acc_Gyro_Ism330dlc_Read(&GyroAccDriverReg->ISM330DLC_Reg_Tab[index], IMS330DLC_Reg_Type_Adr[index].adr, Num);
// Read data to a local buffer
u8_TL3GD20_Reg[index] = GyroAccDriverReg->ISM330DLC_Reg_Tab[index];
//reset the flag when write is done!
ISM330DLC_Update_Regiter_Flag = 0;
}
else if (0x03 == IMS330DLC_Reg_Type_Adr[index].type)
{
if ((1u == ISM330DLC_Update_Regiter_Flag))
{
//write
Acc_Gyro_Imc330dlc_Write(&GyroAccDriverReg->ISM330DLC_Reg_Tab[index], IMS330DLC_Reg_Type_Adr[index].adr, Num);
//reset the flag when write is done!
ISM330DLC_Update_Regiter_Flag = 0;
}
//read
Acc_Gyro_Ism330dlc_Read(&GyroAccDriverReg->ISM330DLC_Reg_Tab[index], IMS330DLC_Reg_Type_Adr[index].adr, Num);
//if write read is not good issue a problem.
// Read data to a local buffer
u8_ISM330DLC_Reg[index] = GyroAccDriverReg->ISM330DLC_Reg_Tab[index];
}
else
{
}
}
}
return 1;
}
else
{
Debugvariable.id_failure++;
return -1;
}
}
My problem is when I read all the registers some of them are messy
and shifted in some cases. It looks like I read more than uint8_t somewhere and overwritten the structure. I read the datasheet all registers are 8 bits.
I pushed my code to git if you want to see the whole code.