I have reflowed an FXOS8700 to my own development card as an breakout to be able to use it in a project. I am now unsure if it works proper or not.
Is the possibility to read but not write a sign of a burnt FXOS8700 in the reflow process????
SPI setting are CPOL=0 and CPHA=0:
I have no problem to read from an address, but problem to read back what was written.
This is my sequence of SPI commands:
// WHO AM I
SPI_ReadFXOS(WHO_AM_I, rbuf, 1);
sprintf_P(buffer_0, PSTR("\r\n::WHO AM I = 0x%X\r\n\r\n"), rbuf[0]);
uart_puts(buffer_0);
=> 0xC7
// Temperature
SPI_ReadFXOS(TEMP, rbuf, 1);
sprintf_P(buffer_0, PSTR("\r\n::TEMP = %i\r\n\r\n"), rbuf[0]);
uart_puts(buffer_0);
=> 21
Both above works as aspected!!!!
// Acc + Mag TEST
SPI_WriteFXOS(CTRL_REG1, 0x00); // Set to standby mode
SPI_ReadFXOS(CTRL_REG1, rbuf, 1);
sprintf_P(buffer_0, PSTR("\r\n::CTRL_REG1 = 0x%X\r\n\r\n"), rbuf[0]);
uart_puts(buffer_0);
SPI_WriteFXOS(M_CTRL_REG1, 0x1F); // 200 Hz hybrid mode
SPI_ReadFXOS(M_CTRL_REG1, rbuf, 1);
sprintf_P(buffer_0, PSTR("\r\n::M_CTRL_REG1 = 0x%X\r\n\r\n"), rbuf[0]);
uart_puts(buffer_0);
=> 0x00
Writing to M_CTRL_REG1 does not work but gives 0x00 back ......
Now I have reflowed another two FXOS8700 vary carefully, and both of them show identical characteristics.
It is not possible to write to a register and than read it back, what can possible be wrong??
Hi Hans-Henrik,
It seems like your both write sequences are not correct. The order of the bits is as follows:
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
Byte 2: DATA[7], DATA[6], DATA[5], DATA[4], DATA[3], DATA[2], DATA[1], DATA[0]
The first byte you are sending is correct, but the MSB bit of the second byte (ADDR[7]) should be "0" and not "1". So instead of sending 0xDB, 0xDB, 0x1F, try to send 0xDB, 0x00, 0x1F. Then send 0x5B, 0x00, 0x00 to read back 0x1F from the M_CTRL_REG1 register.
Hope it helps.
Best regards,
Tomas
Thanks a bizillion times Tomas!
You are my hero and made my day, truly :smileyhappy:
I had used a macro (atmega8) in as if it returned the first bit as set, and it stayed to the second byte ...
Now all three modules work just fine!!!!
Best Regards,
Hans-Henrik
P.S: For anyone interested in atmega8 code looks like:
// Set FXOS8700 in SPI mode
void init_spi(void) {
FXOS_SS_ENABLE; // To open tri-state buffer and set MISO high
MISO_HI; // SPI init demands SA0/MOSI high during reset
FXOS_RESET_HI; // Active high
_delay_ms(1); // ??
FXOS_RESET_LO;
_delay_ms(1); // FXOS8700 Datasheet defines 1ms wait after reset [p.19]
FXOS_SS_DISABLE;
}
// Read values from register FXOS8700
void SPI_ReadFXOS(uint8_t reg, volatile uint8_t* rbuf, uint8_t len) {
FXOS_SS_ENABLE;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
SPDR = cbi(reg,7); // Transmit; clear bit 7 for reading + 7 bits of register address
while(!(SPSR & 1<<SPIF)); // Wait for SPIF flag
SPDR = reg; // Transmit bit 7 of register address
while(!(SPSR & 1<<SPIF)); // Wait for SPIF flag
for(uint8_t i=0; i<len; i++) {
SPDR = 0x00; // Transmit
while(!(SPSR & 1<<SPIF)); // Wait for SPIF flag
rbuf[i] = SPDR; // Clear SPIF flag 2/2
}
}
FXOS_SS_DISABLE; // 2) For ISR context switcher which re-enable SPI unit
}
// Write value to register FXOS8700 <------------------------- ineffektiv loop
void SPI_WriteFXOS(uint8_t reg, uint8_t val) {
FXOS_SS_ENABLE;
uint8_t reg1 = reg;
sbi(reg1,7);
uint8_t wbuf[3] = {reg1, reg, val}; // Two bytes for write bit and address
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
for(uint8_t i=0; i<3; i++) {
SPDR = wbuf[i]; // Transmit
while(!(SPSR & 1<<SPIF)); // Wait for SPIF flag
}
}
FXOS_SS_DISABLE; // 2) For ISR context switcher which re-enable SPI unit
}
Just for illustration, here is an example of writing/reading the value of 0x3D to/from the CTRL_REG1 (0x2A):
Best regards,
Tomas