2025-10-03 4:49 PM - last edited on 2025-10-04 10:42 AM by mƎALLEm
Hello,
I am trying to interface STM32H7 microcontroller with SCL3300 inclinometer, I have attached the SPI configuration and the SPItransfer method.
ConfigSPI_SCL3300()
{
// 52 PA6 SPI1_MISO
// 151 PD7 SPI1_MOSI
// 154 PG11 SPI1_SCK
// 153 PG10 SPI_CS
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOD);
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOG);
//LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOC);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
LL_RCC_HSI_Enable();
LL_RCC_SetCLKPClockSource(LL_RCC_CLKP_CLKSOURCE_HSI);
LL_RCC_SetSPIClockSource(LL_RCC_SPI123_CLKSOURCE_CLKP);
LL_GPIO_InitTypeDef GPIO_InitStruct;
/* SPI1 SCK GPIO pin configuration for PG11 */
GPIO_InitStruct.Pin = LL_GPIO_PIN_11;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOG, &GPIO_InitStruct);
/* SPI1 MISO GPIO pin configuration for PA6 */
GPIO_InitStruct.Pin = LL_GPIO_PIN_6;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* SPI1 MOSI GPIO pin configuration for PD7 */
GPIO_InitStruct.Pin = LL_GPIO_PIN_7;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* SPI1 CS GPIO pin configuration for PG10 */
GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT; // software controlled
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; // idle = high
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
LL_GPIO_Init(GPIOG, &GPIO_InitStruct);
///* SPI1 MUX S GPIO pin configuration for PC8 */
//GPIO_InitStruct.Pin = LL_GPIO_PIN_8;
//GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
//GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
//GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
//GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
//LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
//LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_8); // MUX S low for SPI mode
//Config SPI Master:
LL_SPI_Disable(SPI1);
LL_SPI_DeInit(SPI1);
/* Configure the SPI1 parameters */
LL_SPI_InitTypeDef SPI_InitStruct;
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8; /* from div128 to div4 which 4Mhz recommended operating range */
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX; // no wait between send and rx data
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE; /* SPI MODE 0 */
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW; /* SPI MODE 0 */
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_32BIT; /* 32 bit frame */
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_InitStruct.CRCPoly = 10;
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
LL_SPI_Init(SPI1, &SPI_InitStruct);
LL_SPI_SetStandard(SPI1, LL_SPI_PROTOCOL_MOTOROLA);
LL_SPI_SetTransferSize(SPI1, 0);
LL_SPI_Enable(SPI1);
LL_GPIO_SetOutputPin(GPIOG, LL_GPIO_PIN_10);
}
uint32_t AccelerometerService_SCL3300::SPITransfer32(uint32_t val)
{
uint32_t ret{};
LL_GPIO_ResetOutputPin(GPIOG, LL_GPIO_PIN_10);
//GlobalTimer_Sleep_us(10);
LL_SPI_ClearFlag_SUSP(SPI1);
LL_SPI_StartMasterTransfer(SPI1);
while (!LL_SPI_IsActiveFlag_TXP(SPI1));
LL_SPI_TransmitData32(SPI1, val);
while (!LL_SPI_IsActiveFlag_RXP(SPI1));
ret = LL_SPI_ReceiveData32(SPI1);
while (!LL_SPI_IsActiveFlag_TXC(SPI1));
//LL_SPI_SuspendMasterTransfer(SPI1);
//while (!LL_SPI_IsActiveFlag_SUSP(SPI1));
LL_GPIO_SetOutputPin(GPIOG, LL_GPIO_PIN_10);
GlobalTimer_Sleep_us(10); /* Sleep 10us */
//NanoSleep::nanosleep(10000);
return ret;
}
I am trying to send WHOAMI twice and when I look at the second frame my CRC almost always fails. If anyone can highlight why my CRC fails.
Attaching screenshot of my logic analyzer. CS, SCK, MOSI , MISO respectively.
Thank you
2025-10-07 2:36 AM
@sundar_ wrote:my CRC almost always fails.
Are you sure you are using the correct CRC (with correct initialisation), as described in the Murata datasheet?
via: https://www.murata.com/en-eu/products/sensor/inclinometer/overview/lineup/scl3300
Have you tried using the C implementation which they provide?
2025-10-07 11:18 AM
Yes I am using the same implementation that is in the datasheet
/* Calculate CRC was taken from SCL3300 datasheet */
uint8_t AccelerometerService_SCL3300::CalculateCRC(uint32_t Data)
{
uint8_t BitIndex;
uint8_t BitValue;
uint8_t crcVal;
crcVal = 0xFF;
for (BitIndex = 31; BitIndex > 7; BitIndex--)
{
BitValue = (uint8_t)((Data >> BitIndex) & 0x01);
crcVal = CRC8(BitValue, crcVal);
}
crcVal = (uint8_t)~crcVal;
return crcVal;
}
uint8_t AccelerometerService_SCL3300::CRC8(uint8_t BitValue, uint8_t crcVal)
{
uint8_t Temp;
Temp = (uint8_t)(crcVal & 0x80);
if (BitValue == 0x01)
{
Temp ^= 0x80;
}
crcVal <<= 1;
if (Temp > 0)
{
crcVal ^= 0x1D;
}
return crcVal;
}
bool AccelerometerService_SCL3300::CheckCRC(uint32_t frame)
{
uint8_t rx_crc = (uint8_t)(frame & 0x000000FFu);
//uint32_t MSB_31_8 = frame & 0xFFFFFF00u;
uint8_t calc_crc = CalculateCRC(frame);
return (rx_crc == calc_crc);
}