STM8S - Connect to ADXL345 Acceleration Sensor via Hardware SPI

After software SPI didn't work out I am now trying to connect to the ADXL345 acceleration sensor via hardware SPI of the STM8S103F3. But, of course, problems appeared again, why not. This is my SPI-Init code:

void initSPIMaster(){
GPIOC->DDR = (1<<MOSI) | (1<<SCK) | (0<<MISO); //MOSI & SCK output, MISO input
GPIOC->CR1 = (1<<MOSI) | (1<<SCK); //MOSI& SCK push-pull

GPIOA->DDR |= (1<<CS); //set CS as output
GPIOA->CR1 |= (1<<CS); //set CS as push-pull
GPIOA->ODR |= (1<<CS); //turn CS high

SPI->CR2 = 0b00000000; //2-line unidirectional, Hardware-Slave  management
SPI->CR1 = 0b01111111; //Enable CPHA, CPOL, MASTER; Baudrate: f/256, SPI Enable
}


This is my SPI-Transmit function to write data to the DR-Register:

void SPITransmit(uint8_t data){
while(!(SPI->SR & (1<<1))){
nop(); //wait until transmit buffer is empty
}
SPI->DR = data;
while((SPI->SR & (1<<7))){
nop(); //wait until not busy
}
}


This is my SPIReceive function to read data from the DR-Register:

uint8_t SPIReceive(){
uint8_t registerValue;
while((SPI->SR & (1<<7))){
nop(); //wait until not busy
}
while(!(SPI->SR & (1<<0))){
nop(); //wait until receive buffer is not empty
}
registerValue = (SPI->DR);
nop();
return registerValue;
}


As a initial test I tried to read the DEVID register of the ADXL345 (0x00), it should return 229 as decimal value. And indeed, it did, this is my function to read a register:

void getValueFromRegister(uint8_t reg, uint8_t *val){
uint8_t transmitValue = (0x80 | reg);

GPIOA->ODR &= ~(1<<CS); //CS low
delay_ms(10);
GPIOA->ODR |= (1<<CS); //CS high

delay_ms(10);
}


I also enabled the ADXL345 with this code:

void initADXL345(){
//enable measurements
GPIOA->ODR &= ~(1<<CS); //turn CS low
SPITransmit(0x2D);
SPITransmit(0x08);
GPIOA->ODR |= (1<<CS); //turn CS high
delay_ms(5);

//set FULL_RES & 16g-Range
GPIOA->ODR &= ~(1<<CS); //turn CS low
SPITransmit(0x31);
SPITransmit(0b00001011);
GPIOA->ODR |= (1<<CS); //turn CS high
}


So the next logical step would be to read data from the data registers (0x32-0x37), so I did (x, y, z are global values of type int16_t):

void getXYZValues(){
uint8_t x0,x1,y0,y1,z0,z1;
getValueFromRegister(0x32, &x0);
delay_ms(10);
getValueFromRegister(0x33, &x1);
delay_ms(10);
getValueFromRegister(0x34, &y0);
delay_ms(10);
getValueFromRegister(0x35, &y1);
delay_ms(10);
getValueFromRegister(0x36, &z0);
delay_ms(10);
getValueFromRegister(0x37, &z1);

x = ((x1<<8) | x0);
y = ((y1<<8) | y0);
z = ((z1<<8) | z0);
}


The problem now is:

I always get the value -6683 (decimal) for every axis! And these value isn't even changing if I move the sensor!

For gods sake, why is it so horrible to work with this sensor?

I thought about that maybe CPOL or CPHA is the problem but according to the datasheet they should both be enabled (as I did).

Any ideas, why this is not working? I am really frustrated and I try to get it to work for weeks (if I add the days from my first try with software SPI).

• There is a very big clue in the data; -6683 is 0xFFFFFFFFFFFFE5E5, or 0xE5E5 when limited to a 16 bit value; the ID register returns E5 in its ID. This makes me think you are simply getting repeats of the ID register reads; try reading back the setup registers (0x2D and 0x31) and check they are indeed being set up as you think. If not, it implicates the transmit function. – Peter Smith May 8 '16 at 14:15
• You are completely right! I get the value 8 (decimal) for 0x2D and 0x31 register even though 0x31 should have the value 11 (decimal). But how do i know if the transmit or receive function is faulty? – binaryBigInt May 8 '16 at 14:26
• The receive function is working for a device ID read, and I would therefore surmise it is operational. That leaves the transmit function. Note that the datasheet recommends a burst read of all 6 registers in a single transaction, but it should not be necessary unless you require guaranteed precision. I would suggest a breakpoint in the transmit function immediately after the SPI block data register is loaded; see what is in there. It is interesting that the value in the second register is the same as the first write – Peter Smith May 8 '16 at 14:29
• If i write 0x31 to the DR-Register i get 0x0B as the value of the SPI Data register. Why? – binaryBigInt May 8 '16 at 14:38
• 0x0B is what you are trying to write (0b00001011 = 0x0B) – Peter Smith May 8 '16 at 15:10