Skip to main content
Visitor II
October 9, 2020
Question

I'm trying without much luck to get a accelerometer and magnetometer reading from an FXOS8700.

  • October 9, 2020
  • 1 reply
  • 588 views

My MCU initialisation code looks like this:

GPIO_InitTypeDef gpio = { .Pin = 0, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 };
GPIO_InitTypeDef gpio_spi = { .Pin = GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF5_SPI4 };
 
if(true) { /* gpio and spi */
 __GPIOE_CLK_ENABLE();
 gpio.Pin = SS_pin; 	HAL_GPIO_Init(SS_port, &gpio);
 gpio.Pin = VDD_pin; HAL_GPIO_Init(VDD_port, &gpio);
 gpio.Pin = RST_pin; HAL_GPIO_Init(RST_port, &gpio);
 
 VDD(true);
 SS(true);
 
 if(true) { /* put the FXOS8700 chip into SPI mode */
 delay_ms(10);
 RST(true);
 delay_ms(1);
 RST(false);
 delay_ms(1);
 }
 
 /* spi */
 spi4.Instance = SPI4;
 spi4.Init.Mode = SPI_MODE_MASTER;
 spi4.Init.Direction = SPI_DIRECTION_2LINES;
 spi4.Init.DataSize = SPI_DATASIZE_8BIT;
 spi4.Init.CLKPolarity = SPI_POLARITY_LOW;					/* SPI_POLARITY_LOW for mode 0, SPI_POLARITY_HIGH for mode 3 */
 spi4.Init.CLKPhase = SPI_PHASE_1EDGE;						/* SPI_PHASE_1EDGE for mode 0, SPI_PHASE_2EDGE for mode 3 */
 spi4.Init.NSS = SPI_NSS_SOFT;
 spi4.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;	// max frew is 1MHz
 spi4.Init.FirstBit = SPI_FIRSTBIT_MSB;
 spi4.Init.TIMode = SPI_TIMODE_DISABLED;
 spi4.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
 
 __SPI4_CLK_ENABLE();
 if(HAL_SPI_Init(&spi4) != HAL_OK) {
 errorhandler(filename, __LINE__);
 }
 
 __GPIOE_CLK_ENABLE();
 HAL_GPIO_Init(GPIOE, &gpio_spi);
 }

Followed by a call to whoami to confirm that SPI is set up correctly which seems to work fairly reliably

uint8_t whoami = readreg(WHO_AM_I);
 
if(whoami != 0xc7) { /* WHO_AM_I should return 0xc7 */
 return false;
}

Then I set up the FXOS8700 itself:

writereg(CTRL_REG1, 0x00);			// place into standby mode
writereg(M_CTRL_REG1, 0x1F);	// configure magnetometer
writereg(M_CTRL_REG2, 0x20);	// configure magnetometer
writereg(XYZ_DATA_CFG, 0x01);	// configure accelerometer 4G range
writereg(CTRL_REG2, 0x02);		// configure accelerometer hires
writereg(CTRL_REG1, 0x15);		// configure accelerometer 100Hz A+M

After that, once a second, I poll the FXOS8700:

const uint8_t* rx = readreg(OUT_X_MSB, 13);
 
if(rx == 0 || rx[0] == 0) {
 return;
}
 
const uint8_t* xyz = &rx[1];
 
if(acc != 0) { /* extract accelerometer values */
 acc[0] = (int16_t)((xyz[0] << 8) | xyz[1]);
 acc[1] = (int16_t)((xyz[2] << 8) | xyz[3]);
 acc[2] = (int16_t)((xyz[4] << 8) | xyz[5]);
}
 
if(mag != 0) { /* extract accelerometer values */
 mag[0] = (int16_t)((xyz[6] << 8) | xyz[7]);
 mag[1] = (int16_t)((xyz[8] << 8) | xyz[9]);
 mag[2] = (int16_t)((xyz[10] << 8) | xyz[11]);
}

But either status is non-zero or the values read into acc and mag never change.

I'm guessing that this is something to do with the FXOS8700 initialisation registers, but I'm totally at a loss for what to use instead.

    This topic has been closed for replies.

    1 reply

    ST Employee
    October 9, 2020

    Hi @DCarr.1​ ,

    please note first that the FXOS8700 product is from NXP, and not from ST... ;)

    So I would suggest you to compare your code with the configuration function in the datasheet p.26 or ask on NXP support community.

    -Eleon