cancel
Showing results for 
Search instead for 
Did you mean: 

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

DCarr.1
Senior

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.

1 REPLY 1
Eleon BORLINI
ST Employee

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