2020-10-09 06:59 AM
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.
2020-10-09 07:49 AM