I am attempting to use the FXOS8700 in SPI mode due to the faster read / write times associated with SPI (higher possible bus speed). I have set up the SPI bus to run with the following parameters which are consistent with the FXOS8700 data sheet:
CLK: 1 MHz
Order: MSB First
CPOL: Rising/Falling
CPHA: Sample/Setup
I have verified the above settings on an oscilloscope so I know that the bus is set up correctly.
In order to get the FXOS into SPI mode, I tri-state the MISO pin before toggling the reset pin, and waiting the required time for the auto detection circuit to put the device into SPI mode. I then attempt to read the WHO_AM_I register and get the value 0x1e instead of 0xc7 which is what I would expect. Below is the code I am using to reset the device and read the WHO_AM_I register:
#define FXOS_MISO 26
#define FXOS_CS 11
#define FXOS_RST 3
void FXOSSPI()
{
// Tri-state MISO
pinMode( FXOS_MISO, TRI_STATE );
delay( 10 );// Reset the FXOS
digitalWrite( FXOS_RST, HIGH );
digitalWrite( FXOS_RST, LOW );
delay( 1 );// Set up the bus
SPISettings _settings = SPISettings( 1000000, MSBFIRST, SPI_MODE0 );
SPI1.beginTransaction( _settings );// Read WHO_AM_I
uint8_t tx[3] = { ( 0x0D >> 1 ) & 0xFF, ( 0x0D << 7 ) & 0xFF , 0xFF };
digitalWrite( FXOS_CS, LOW );for( uint8_t i = 0; i < 3; i++)
buff[i] = SPI1.transfer( tx[i] );digitalWrite( FXOS_CS, HIGH );
SPI1.end();
}
After I run that function I check the contents of buff using a break point and ICD, the contents of buff are:
buff[0] = 0xFF
buff[1] = 0xFF
buff[2] = 0x1E
Obviously, bytes 0, and 1 are DC because we are writing the R/W bits and the register address, but byte 2 should be 0xC7. Not really sure what is going on here, I have looked at this many times under a scope, verified SPI register settings via ICD, slowed down the clock rate, etc. Still get the same results. Anybody else getting this problem? The only thing I can think of now is that my FXOS is damaged or something.
Solved! Go to Solution.
Hi Warren,
I think I found where the problem is. You are not addressing the WHO_AM_I register (0x0D) correctly.
As shown in the datasheet:
Byte 0: R/W, ADDR[6], ADDR[5], ADDR[4], ADDR[3], ADDR[2], ADDR[1], ADDR[0]
Byte 1: ADDR[7], X, X, X, X, X, X, X
In your case tx[0] = ( 0x0D >> 1 ) & 0xFF while the correct way is tx[0] = 0x0D & 0x7F. Similarly tx[1] = ( 0x0D << 7 ) & 0xFF while the correct form is tx[1] = 0x0D & 0x80.
Here is my complete read a register function:
/******************************************************************************
* Read a byte from the FXOS8700CQ
*
* Byte 0: 0,ADDR[6],ADDR[5],ADDR[4],ADDR[3],ADDR[2],ADDR[1],ADDR[0]
* Byte 1: ADDR[7],0,0,0,0,0,0,0
* Byte 2: 0,0,0,0,0,0,0,0
******************************************************************************/
unsigned char FXOS8700CQ_ReadRegister(unsigned char RegisterAddress)
{
unsigned char i;
CS_Enable;
while (!(SPI0_S & SPI_S_SPTEF_MASK));
SPI0_D = 0x7F & RegisterAddress;
while (!(SPI0_S & SPI_S_SPRF_MASK));
i = SPI0_D;
while (!(SPI0_S & SPI_S_SPTEF_MASK));
SPI0_D = 0x80 & RegisterAddress;
while (!(SPI0_S & SPI_S_SPRF_MASK));
i = SPI0_D;
while (!(SPI0_S & SPI_S_SPTEF_MASK));
SPI0_D = 0x00; // Dummy byte
while (!(SPI0_S & SPI_S_SPRF_MASK));
i = SPI0_D;
CS_Disable;
return i;
}
I hope it helps.
Best regards,
Tomas
Hi Tomas,
I can't believe I missed that! Just goes to show the value of having a fresh set of eyes on your code. Thank you, everything is working as planned now.
- Warren
You are very welcome, Warren.
Very glad to hear it is working now!
Best regards,
Tomas
Hi Warren,
I think I found where the problem is. You are not addressing the WHO_AM_I register (0x0D) correctly.
As shown in the datasheet:
Byte 0: R/W, ADDR[6], ADDR[5], ADDR[4], ADDR[3], ADDR[2], ADDR[1], ADDR[0]
Byte 1: ADDR[7], X, X, X, X, X, X, X
In your case tx[0] = ( 0x0D >> 1 ) & 0xFF while the correct way is tx[0] = 0x0D & 0x7F. Similarly tx[1] = ( 0x0D << 7 ) & 0xFF while the correct form is tx[1] = 0x0D & 0x80.
Here is my complete read a register function:
/******************************************************************************
* Read a byte from the FXOS8700CQ
*
* Byte 0: 0,ADDR[6],ADDR[5],ADDR[4],ADDR[3],ADDR[2],ADDR[1],ADDR[0]
* Byte 1: ADDR[7],0,0,0,0,0,0,0
* Byte 2: 0,0,0,0,0,0,0,0
******************************************************************************/
unsigned char FXOS8700CQ_ReadRegister(unsigned char RegisterAddress)
{
unsigned char i;
CS_Enable;
while (!(SPI0_S & SPI_S_SPTEF_MASK));
SPI0_D = 0x7F & RegisterAddress;
while (!(SPI0_S & SPI_S_SPRF_MASK));
i = SPI0_D;
while (!(SPI0_S & SPI_S_SPTEF_MASK));
SPI0_D = 0x80 & RegisterAddress;
while (!(SPI0_S & SPI_S_SPRF_MASK));
i = SPI0_D;
while (!(SPI0_S & SPI_S_SPTEF_MASK));
SPI0_D = 0x00; // Dummy byte
while (!(SPI0_S & SPI_S_SPRF_MASK));
i = SPI0_D;
CS_Disable;
return i;
}
I hope it helps.
Best regards,
Tomas