cancel
Showing results for 
Search instead for 
Did you mean: 

Driving ADXL345 via SPI

Khansokhua
Associate III

Board: STM32F407G-DISC1

IDE : StmCubeIDE

Hello,

      I am trying to drive ADXL345 accelerometer sensor via SPI. I succeed in receiving the device address (0xE5).

However, afterwards, when I tried to read two registers' value consecutively. I always read the first read's value, so they are both the same value. I have not figured it out yet. I set SSOE bit and HW NSS is also set. Could anyone explain where I missed? Thanks in advance.

Have a nice day

void spixInit(const SPI_Handle_t* handler) { SPI_RegDef_t* spi = handler->spiSelect; if(spi == SPI1) SPI1_CLOCK_ENABLE(); else if(spi == SPI2) SPI2_CLOCK_ENABLE(); else if(spi == SPI3) SPI3_CLOCK_ENABLE(); spi->SPI_CR1 = 0; spi->SPI_CR1 |= ( handler->pinConfig.cphase << 0); spi->SPI_CR1 |= ( handler->pinConfig.cpol << 1); spi->SPI_CR1 |= ( handler->pinConfig.mode << 2); spi->SPI_CR1 |= ( handler->pinConfig.baudRate << 3); spi->SPI_CR1 |= ( handler->pinConfig.firstBit << 7); spi->SPI_CR1 |= ( handler->pinConfig.dataSize << 11); /* * Default full-duplex two wire * Default NSS in HW mode, since we will use single slave mostly */ if(!(spi->SPI_CR1 & (1u << 9))) // if HW NSS enabled spi->SPI_CR2 |= (1u << 2); // set slave select automatically spi->SPI_CR1 |= ( 1u << 13); // CRC enable spi->SPI_CR1 |= ( 1u << 6); // peripheral enable } void spixSendDataByte(SPI_RegDef_t* spi, const uint8_t* buffer, size_t size) { while(size--) { while(!(spi->SPI_SR & (1u << 1))) ; // wait until TX buffer empty spi->SPI_DR = *buffer++; } while(spi->SPI_SR & (1u << 7)) ; // wait until busy flag reset } void spixReceiveDataByte(SPI_RegDef_t* spi, uint8_t* buffer, size_t size) { while(size--) { while(!(spi->SPI_SR & (1u << 0))) ; // wait until RX buffer is not empty *buffer++ = spi->SPI_DR; } while(spi->SPI_SR & (1u << 7)) ; // wait until busy flag reset } uint8_t readRegisterDataAdxl345(uint8_t registerAddress ) // { uint8_t readBuffer = 0; registerAddress |= 0x80; // set for read operation //gpioWritePin(GPIOA, GPIO_PIN_4, 0); spixSendDataByte(SPI1, &registerAddress , 1); spixReceiveDataByte(SPI1, &readBuffer, 1); //gpioWritePin(GPIOA, GPIO_PIN_4, 1); return readBuffer; } int main(void) { /* * PA4 - PA5 - PA6 - PA7 pins must be configured in AF mode for SPI1 */ GPIO_Handle_t SP1_NSS_PA4 = { // on ADXL345 connected to CS pin .PORTNAME = GPIOA, .PINCONF.PIN = GPIO_PIN_4, .PINCONF.MODE = GPIO_MODE_ALTARNATE, .PINCONF.OTYPE = GPIO_OTYPE_PP, .PINCONF.OSPEED = GPIO_OSPEED_HIGH, .PINCONF.PUPD = GPIO_PUPD_NO, .PINCONF.AF = AF5 }; GPIO_Handle_t SP1_SCK_PA5 = { // on ADXL345 connected to SCL pin .PORTNAME = GPIOA, .PINCONF.PIN = GPIO_PIN_5, .PINCONF.MODE = GPIO_MODE_ALTARNATE, .PINCONF.OTYPE = GPIO_OTYPE_PP, .PINCONF.OSPEED = GPIO_OSPEED_HIGH, .PINCONF.PUPD = GPIO_PUPD_NO, .PINCONF.AF = AF5 }; GPIO_Handle_t SP1_MISO_PA6 = { // on ADXL345 connected to SDO pin .PORTNAME = GPIOA, .PINCONF.PIN = GPIO_PIN_6, .PINCONF.MODE = GPIO_MODE_ALTARNATE, .PINCONF.OTYPE = GPIO_OTYPE_PP, .PINCONF.OSPEED = GPIO_OSPEED_HIGH, .PINCONF.PUPD = GPIO_PUPD_PU, .PINCONF.AF = AF5 }; GPIO_Handle_t SP1_MOSI_PA7 = { // on ADXL345 connected to SDA pin .PORTNAME = GPIOA, .PINCONF.PIN = GPIO_PIN_7, .PINCONF.MODE = GPIO_MODE_ALTARNATE, .PINCONF.OTYPE = GPIO_OTYPE_PP, .PINCONF.OSPEED = GPIO_OSPEED_HIGH, .PINCONF.PUPD = GPIO_PUPD_NO, .PINCONF.AF = AF5 }; gpioInit(&SP1_NSS_PA4); gpioInit(&SP1_SCK_PA5); gpioInit(&SP1_MISO_PA6); gpioInit(&SP1_MOSI_PA7); /* * SPI configuration must be made according to the ADXL345 requirements */ SPI_Handle_t SPI1_ADXL345 = { .spiSelect = SPI1, .pinConfig.mode = SPI_DEVICE_MASTER, .pinConfig.baudRate = SPI_BAUD_RATE_PRESC_16, // 1 MHz clock, since main clock 16 Mhz HSI .pinConfig.cpol = SPI_CPOL_IDLE_1, .pinConfig.cphase = SPI_CPHASE_SECOND_EDGE, .pinConfig.dataSize = SPI_DATA_SIZE_8, .pinConfig.firstBit = SPI_MSB_FIRST, }; spixInit(&SPI1_ADXL345); uint8_t deviceAddressADXL345 = readRegisterDataAdxl345(DEVID_BASE_ADDR); // 0xE5 uint8_t bwRateVal = readRegisterDataAdxl345(BW_RATE_BASE_ADDR); // 0xE5 while(1) { } }
View more

 

1 REPLY 1
tjaekel
Lead

ADXL345 datasheet says:
"To read or write multiple bytes in a single transmission, the multiple-byte bit, located after the R/ W bit in the first byte transfer analog.com (MB in Figure 37 to Figure 39), must be set."

Have you done?