2020-11-02 10:53 AM
The SPI does not work correctly in the slave mode when CPOL=0 and CPHA=0 or CPOL=1 and CPHA=1.
When transmitting some bytes, the slave SPI distorts the data and terminates the processing of the frame prematurely (during the seventh pulse of the clock signal).
Other bytes are transmitted correctly.
Test code (0x03 raises an error, 0xFF does not):
/*
MCU: STM32F100RB
SPI1:
PA4 - NSS;
PA5 - SCK;
PA6 - MISO;
PA7 - MOSI.
SPI2:
PB12 - NSS;
PB13 - SCK;
PB14 - MISO;
PB15 - MOSI.
Connections: PA4-PB12; PA5-PB13; PA6-PB14; PA7-PB15.
*/
#include "stm32f10x.h"
const uint32_t CPOL=SPI_CR1_CPOL*0;
const uint32_t CPHA=SPI_CR1_CPHA*0;
uint8_t a1=0x5A; // Byte to transfer through the SPI1.
uint8_t a2=0x03; // Byte to transfer through the SPI2.
//uint8_t a2=0xFF;
//uint8_t a2=0x3C;
uint8_t b1=0; // The byte received by the SPI1.
uint8_t b2=0; // The byte received by the SPI2.
int main(void)
{
RCC->APB2ENR|=
RCC_APB2ENR_SPI1EN|
RCC_APB2ENR_IOPAEN|
RCC_APB2ENR_IOPBEN;
RCC->APB1ENR|=RCC_APB1ENR_SPI2EN;
// PA4 (SPI1_NSS): alt. out, push-pull, high speed
// PA5 (SPI1_SCK): alt. out, push-pull, high speed
// PA6 (SPI1_MISO): float input
// PA7 (SPI1_MOSI): alt. out, push-pull, high speed
GPIOA->CRL=
GPIOA->CRL&~0xFFFF0000|
0xB4BB0000;
// PB12 (SPI2_NSS): input
// PB13 (SPI2_SCK): input
// PB14 (SPI2_MISO): alt. out, push-pull, high speed
// PB15 (SPI2_MOSI): input
GPIOB->CRH=
GPIOB->CRH&~0xFFFF0000|
0x4B440000;
SPI1->CR1= // Clear all bits except...
SPI_CR1_MSTR| // master
SPI_CR1_BR| // the lowest speed
CPOL|
CPHA;
SPI1->CR2=
SPI1->CR2&~0xE7| // Clear all unreserved bits.
SPI_CR2_SSOE; // NSS is output.
SPI2->CR1= // Clear all bits except...
CPHA|
CPOL;
SPI2->CR2&=~0xE7; // Clear all unreserved bits.
SPI1->CR1|=SPI_CR1_SPE;
SPI2->CR1|=SPI_CR1_SPE;
while(!(SPI2->SR&SPI_SR_TXE)) {}
SPI2->DR=a2;
while(!(SPI1->SR&SPI_SR_TXE)) {}
SPI1->DR=a1;
while(!(SPI1->SR&SPI_SR_RXNE)) {}
b1=SPI1->DR;
while(!(SPI2->SR&SPI_SR_RXNE)) {}
b2=SPI2->DR;
if(b1!=a2||b2!=a1)
{
// ERROR!!!
}
while(true) {}
}
2020-11-02 03:31 PM
What exactly are the received values and where is the mismatch?
Observe the pins using oscilloscope.
Try to set OSPEEDR to higher setting.
JW
2020-11-03 08:36 AM
2020-11-03 09:20 AM
Yes I don't use the 'F1, am aware that GPIO is different but don't really know the exact implementation. I see you know what I am talking about nevertheless :)
Very nice diagram. Care to tell us how did yo produce it?
The upper 3 signals, they are from master or slave? Can you try to produce the same for the other SPI?
Is there any other hardware connected, or are the lines only plainly looped back to themselves?
Try perhaps lowering the "OSPEEDR" setting, especially for clock.
JW
2020-11-03 10:58 AM
> Very nice diagram. Care to tell us how did yo produce it?
This is my logic self analyzer technique. The DMA, on a timer signal, reads SPIx->SR and the state of the pins (GPIOx->IR) and stores it in a memory buffer. Then we transfer the accumulated data to a PC for processing.
> The upper 3 signals, they are from master or slave? Can you try to produce the same for the other SPI?
Those are from slave. It is for master:> Is there any other hardware connected, or are the lines only plainly looped back to themselves?
They are only looped back to themselves.
> Try perhaps lowering the "OSPEEDR" setting, especially for clock.
And yes! The device operates normally in all modes after decreasing the speed of outputs. I should think.
Thanks a lot for your help!