1
votes

I'm trying to make basic SPI communication between 2 stm32 devices. HAL is used for that purpose. Idea is to exchange data between 2 MCU every 1 sec. So I create timer which purpose is to generate interrupt every 1 sec (timer is used to set flag for start SPI communication). MCU are configurated to work in full duplex mode (1 master and 1 slave).

My problem is next: 2 MCU communicate as expected when SPI is configurated to work on lower bandwidth (when prescaler is 256 or 128). As speed increases data collect more and more garbage on MOSI line. Basically MISO line don't works as expected. MISO line stay high (look picture) when it should be low.

Master code:

#define SPI_SLAVE_SYNBYTE     (0xAC)
#define SPI_MASTER_SYNBYTE    (0x53)

bool flagSpi1 = false;
uint8_t rxSpi[10] = {0};
uint8_t txSpi[10] = "Milan";

void Synch(void)
{
    uint8_t txAck = SPI_MASTER_SYNBYTE;
    uint8_t rxAck = 0;
    do
    {
        if(HAL_SPI_TransmitReceive_DMA(&hspi3, (uint8_t *)&txAck, (uint8_t *)&rxAck, 1) != HAL_OK)
        {
            Error_Handler();
        }
        while(HAL_SPI_GetState(&hspi3) != HAL_SPI_STATE_READY){}
    }while(rxAck != SPI_SLAVE_SYNBYTE);
}
void Receive_Spi_Master(void)
{
    if(HAL_SPI_Receive_DMA(&hspi3, rxSpi, 10) != HAL_OK)
    {
        Error_Handler();
    }
    while(HAL_SPI_GetState(&hspi3) != HAL_SPI_STATE_READY){}
}
void Transmit_Spi_Master(void)
{
    if(HAL_SPI_Transmit_DMA(&hspi3, txSpi, 10) != HAL_OK)
    {
        Error_Handler();
    }
    while(HAL_SPI_GetState(&hspi3) != HAL_SPI_STATE_READY){}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM5)
    {
        flagSpi1 = true;
    }
}
main(void)
{
    Init_Part();      

    while(1)
    {
        if(flagSpi1)
        {
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
            Synch();
            Receive_Spi_Master();
            Synch();
            Transmit_Spi_Master();
            Synch();
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
            Send_Data_To_Terminal_Via_Uart(rxSpi);
            HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15);
            flagSpi1 = false;
        }
   }   

}

Slave code:

#define SPI_SLAVE_SYNBYTE     (0xAC)
#define SPI_MASTER_SYNBYTE    (0x53)

uint8_t txSpi[10] = "Test";
uint8_t rxSpi[10];

void Synch(void)
{
    uint8_t txAck = SPI_SLAVE_SYNBYTE;
    uint8_t rxAck = 0;

    do
    {
        if(HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t *)&txAck, (uint8_t *)&rxAck, 1) != HAL_OK)
        {
            Error_Handler();
        }
        while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY){}

    }while(rxAck != SPI_MASTER_SYNBYTE);
}

void Transmit_Spi_Slave(void)
{
    if(HAL_SPI_Transmit_DMA(&hspi1, txSpi, 10) != HAL_OK)
    {
        Error_Handler();
    }
    while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY){}
}

void Receive_Spi_Slave(void)
{
    if(HAL_SPI_Receive_DMA(&hspi1, rxSpi, 10) != HAL_OK)
    {
        Error_Handler();
    }
    while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY){}
}

main(void)
{
    Init_Part();

    while (1)
    {
        if(!HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4))
        {
            Synch();
            Transmit_Spi_Slave();
            Synch();
            Receive_Spi_Slave();
            Synch();
            HAL_Delay(3);
        }
    }
}

When code "works" (it works but I think that MISO line is wrong, this picture represent low speed SPI - prescaler is 256) enter image description here

1
Who did tell you that it should be low?0___________
Noone, diagrams which I found on internet doesn't have MISO line high in idlesubavet995
it sends something random when idle - it is normal behaviour (at least for STM32 uCs). if you want to make sure zeroes are clocked out, you need to feed data register with zeroes.0___________
I’m voting to close this question because it belongs on electronics.stackexchange.comClifford
@P__J__ : I know what he is asking, but he refers to data errors at high- speed. Why then is he asking about the idle state at low speed? It seems, he thinks that the fact that the a MISO state is not as he expected is somehow related to the errors. It's an X-Y problem. We can tell him why the MISO is high; that won't solve his data errors. It is most likely a signal integrity issue, or he has simply exceeded the spec. of the part. Whatever is pulling the MISO high however, may also be affecting the signal integrity of course.Clifford

1 Answers

0
votes

When Idle, MISO doesn't matter, nothing should be reading it. Ignore that.

When you are getting garbage, what does your screen look like? Are all your pins configured for high speed? Can both devices communicate at high speed? Can you show us something basic configured for low speed then the same output for high speed?