2025-02-26 11:58 AM
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, ®isterAddress , 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)
{
}
}