2018-12-03 08:11 AM
Hello,
I'm using a Murata CMWX1ZZABZ embedding a STM32L082 and the HAL v1.8.1.
HAL_SPI_TransmitReceive() returns wrong LSB data :
-expected : 0x33, received : 0x33 : OK
-expected : 0xAA33, received : 0xAB32 : error
-expected : 0x00, 0x01, 0x02, 0x03..., 0xFE, 0xFF, received : 0x01 0x00, 0x03, 0x02, ..., 0xFF, 0xFE : error
The logic analyser shows the expected values from a 23LC1024 SPI memory slave :
The two last bytes are AA33 as expected.
Here is the initialization function and the receive function wrapper :
SPI_HandleTypeDef _hspi;
void configureSPI(void)
{
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
_hspi.Instance = SPI2;
_hspi.Init.Mode = SPI_MODE_MASTER;
_hspi.Init.Direction = SPI_DIRECTION_2LINES;
_hspi.Init.DataSize = SPI_DATASIZE_8BIT;
_hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
_hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
_hspi.Init.NSS = SPI_NSS_SOFT;
_hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
_hspi.Init.FirstBit = SPI_FIRSTBIT_MSB;
_hspi.Init.TIMode = SPI_TIMODE_DISABLE;
_hspi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
HAL_SPI_Init(&_hspi);
/* Enable the peripheral clock of GPIOB */
RCC->IOPENR |= RCC_IOPENR_GPIOBEN;
/* (1) Select AF mode (10) on PB12, PB13, PB14, PB15 */
/* (2) AF0 for SPI2 signals */
GPIOB->MODER = (GPIOB->MODER
& ~(GPIO_MODER_MODE12 | GPIO_MODER_MODE13 | \
GPIO_MODER_MODE14 | GPIO_MODER_MODE15))\
| (GPIO_MODER_MODE12_1 | GPIO_MODER_MODE13_1|\
GPIO_MODER_MODE14_1 | GPIO_MODER_MODE15_1); /* (1) */
GPIOB->AFR[1] = (GPIOB->AFR[1] & \
~((0xF<<(4*4)) | (0xF<<(4*5)) |\
(0xF<<(4*6)) | ((uint32_t)0xF<<(4*7)))); /* (2) */
}
size_t spiRead(void* self, void* data, size_t size)
{
(void)(self);
uint8_t* d = data;
memset(d, 0xff, size);
if(HAL_SPI_TransmitReceive(&_hspi, d, d, size, 100) != HAL_OK)
{
return 0;
}
/* prints ab32 instead of aa33 */
for(size_t i = 0; i < size; i++)
{
// d[i] ^= 1; /* toggle last bit, FIXME, why ? */
printf("%02x", d[i]);
}
return size;
}
I saw several similar questions but none gave a working answer. Any idea ?
Thank you.
Solved! Go to Solution.
2018-12-03 09:18 AM
Set SPI_SCK pin's drive higher in OSPEEDR.
See Last data bit or CRC calculation may be corrupted for the data received
in master mode depending on the feedback communication
clock timing with respect to the APB clock (SPI or I2S) erratum.
JW
2018-12-03 09:18 AM
Set SPI_SCK pin's drive higher in OSPEEDR.
See Last data bit or CRC calculation may be corrupted for the data received
in master mode depending on the feedback communication
clock timing with respect to the APB clock (SPI or I2S) erratum.
JW
2018-12-04 01:20 AM
Thank you, It worked.
GPIOB->OSPEEDR |= (0x3 << 26);
Or using the HAL GPIO init function :
pin.Mode = GPIO_MODE_AF_PP;
pin.Pull = GPIO_PULLUP;
pin.Alternate = GPIO_AF0_SPI2;
pin.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
I reproduce the same error when the speed is "very high" but the mode is "open drain" instead of "push pull".
I found the erratum you are talking about in the ES0293 document related to the STM32L072 µC.
Mickael