cancel
Showing results for 
Search instead for 
Did you mean: 

L3GD20H can't set Low_ODR bit

MMacL.12
Associate

Hi everyone,

I am using a L3GD20H gyro on a custom board. I am successfully talking to it and have been able to set the following registers to values:

CTRL1_reg: 0x0F (power enabled, all axes enabled)

CTRL3_reg: 0x08 (INT2 set for data ready signal)

CTRL4_reg: 0x80 (BDU set and FS set to 245 dps)

However, I am also trying to set the Low_ODR bit in the LOW_ODR (0x39) register to reduce the update rate. For some reason, it always comes back with a reading of 0. Is there something I am missing here? I've tried setting the bit before and after setting the power enabled bit in register CTRL1_reg, but that didn't work. Pulling my hair a bit, since it's likely something stupid, but I can't seem to see what the problem is. Any help would be appreciated.

3 REPLIES 3
Miroslav BATEK
ST Employee

I'm not able to replicate the issue.

Can you share a part of your code?

Didn't you mix up the Low_ODR bit with SW_RES which is automatically cleared?

MMacL.12
Associate

I don't think I am mixing up those two bits. Here are some code snippets:

/*
   * Need to set LOW_ODR register to set low odr (if necessary)
   * if not required, comment out this routine
   */
  ret = ST_gyro_LOW_ODR_set(I2C0, L3G20H_I2C_ADD_H, PROPERTY_ENABLE, L3G20H_LOW_ODR);
  if(ret == 2)
  {
	  printf("Function ST_gyro_LOW_ODR_set completed ok \n");
  }
  else
  {
	  printf("Function ST_gyro_LOW_ODR_set did NOT complete ok, with code %i \n", ret);
  }

This one is in the main() routine. PROPERTY_ENABLE is define as '1', and L3G20H_LOW_ODR is the address, and defined as '0x39'

#define L3G20H_LOW_ODR					0x39U
typedef struct {
	uint8_t val;
	struct bitwise_L3lowode{
		uint8_t low_odr					:1;
		uint8_t not_used01				:1;
		uint8_t sw_res					:1;
		uint8_t i2c_dis					:1;
		uint8_t not_used02				:1;
		uint8_t drdy_hl					:1;
		uint8_t not_used03				:1;
		uint8_t not_used04				:1;
	}bitwise;
} L3G20H_low_odr_t;

Above code snippet is in my L3G20H.h library, showing how the bits are outlined.

int32_t ST_gyro_LOW_ODR_set(I2C_TypeDef *i2c, uint8_t addr, uint8_t val, uint8_t subAddr)
{
	I2C_TransferSeq_TypeDef seq;
	I2C_TransferReturn_TypeDef ret;
	uint8_t i2c_read_data[1];
	uint8_t i2c_write_data[2];
	L3G20H_low_odr_t low_odr;
 
	seq.addr = addr;
	seq.flags = I2C_FLAG_WRITE_READ;
	/*
	 * need to get value of ctrl4 register before we modify and write it
	 *
	 */
	i2c_write_data[0] = subAddr;
	seq.buf[0].data = i2c_write_data;
	seq.buf[0].len = 1;
	/*
	 * location to store register
	 */
	seq.buf[1].data = i2c_read_data;
	seq.buf[1].len = 1;
	/*
	 * call transfer routine
	 */
	ret = I2CSPM_Transfer(i2c,&seq);
	if(ret != i2cTransferDone)
		return (int)ret;
	low_odr.val = i2c_read_data[0];
	low_odr.bitwise.low_odr = val;
 
	/*
	 * Now we need to perform the write of the data back into the ctrl_reg4 location
	 */
	seq.addr = addr;
	seq.flags = I2C_FLAG_WRITE;
	i2c_write_data[0] = subAddr;
	i2c_write_data[1] = low_odr.val;
	seq.buf[0].data = i2c_write_data;
	seq.buf[0].len = 2;
	seq.buf[1].data = i2c_read_data;
	seq.buf[1].len = 0;
	ret = I2CSPM_Transfer(i2c,&seq);
	if(ret != i2cTransferDone)
		return (int)ret;
	return (int)2;
}

This last code snippet is the read/write I2C to set the LOW_ODR bit.

Thanks again for any help.

hi,

i am also using this chip , but i have some problem with the interrupt , can you tell me how to set the interrupt on int2.

Used to determine when new measurement data sets are avaliable for reading. This signal is represented by the XYZDA bit of the STATUS register.