2022-06-22 12:24 PM
I have a peripheral I am communicating to using both a Raspberry Pi and also STM32G0B1 (two different devices, two different setups)
I am basically trying to reproduce successful communications that the Pi us doing to this peripheral on the STM32 platforms. I am having some strange results.
The CS line seems to be going low or high, too early/late causing bits to be read that shouldn't be there.
I'm sending 3 separate frames. 4 bytes, 10 bytes, 1 byte. There is no input being read, so those lines can be ignored.
Below I am showing the output comparisons between the RPi and STM32.
The graphs below show the following signals:
SDO
SDI <-- no traffic on any signal
CS
CLK
4 bytes frame on Rpi, matches code:
4 bytes on STM32 (should match above):
It can be seen that it appears the bits are shifted 1 to the left here.
The 10 byte frame:
Same again with the STM32:
The final frame is a single byte, the number '8'
On the Rpi it looks like this:
The STM32 reads this as 11
Here it looks like the CS line line stay low for too long causing a 1 to be read, where in the RPI it can be seen that CS goes high right at the end of the last byte.
My code uses the HAL libraries and the sending function is simple:
void spi_transfer(uint8_t board, uint8_t *pData, uint16_t Size) {
HAL_StatusTypeDef status;
HAL_GPIO_WritePin(SPI_CE0_GPIO_Port, SPI_CE0_Pin, GPIO_PIN_RESET);
status = HAL_SPI_Transmit(&hspi1, pData, Size, 100);
HAL_GPIO_WritePin(SPI_CE0_GPIO_Port, SPI_CE0_Pin, GPIO_PIN_SET);
if (status != HAL_OK) {
serprintf("Error writing to SPI on board: %i. (%i)\n\r", board, status);
}
}
I've experimented with the clock speed, and some other settings. But nothing seemed to help.
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
Thanks for any tips
Solved! Go to Solution.
2022-06-23 07:51 AM
There are 4 SPI modes, set by 2 bits, traditionally called CPOL and CPHA. Read the SPI chapter in RM.
You set them
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
i.e. CPOL=0, CPHA=0, and the SPI waveform conforms that.
The RPi waveform does not conform that, it is obviously CPOL=0 CPHA=1, and the LA is set to this mode, too.
JW
2022-06-22 03:58 PM
Increase SCK pin's drive in GPIO_OSPEEDR.
JW
2022-06-23 05:28 AM
Thanks. I've tried to change the PIN speed to all possibilities:
00 2 MHz (low)
01 25 MHz (medium)
10 50 MHz (high)
11 100 MHz (very high)
Using just the final frame as an example, I can see that there wasn't a noticeable change.
2022-06-23 07:51 AM
There are 4 SPI modes, set by 2 bits, traditionally called CPOL and CPHA. Read the SPI chapter in RM.
You set them
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
i.e. CPOL=0, CPHA=0, and the SPI waveform conforms that.
The RPi waveform does not conform that, it is obviously CPOL=0 CPHA=1, and the LA is set to this mode, too.
JW
2022-06-23 09:16 AM
Interesting. Thanks for that. I should have drawn the lines, but I wasn't aware of workings of CPOL and CPHA. Confirmed that with my Logic Analyzer setting CPOL=0 and CPHA=1 decodes the Rpi. Setting CPOL=0 and CPHA=0 properly decodes the SPI.
Now to properly communicate to the peripheral I am not sure if I need CPHA=1 or not. I am going to set up my logic analyzer to determine that but need to rewire some things.
2022-06-23 10:21 AM
Want to close the loop on this for anyone who finds this thread in the future. The above issue is a decoding issue. The difference between the RPI and the STM32 is in fact the CPHA being set to 1 vs 0 (RPI vs STM32)
Once I set the decoder correctly the data was accurate.
I also had to set CPHA to 1 in my code in order to communicate with the peripheral correctly.