AnsweredAssumed Answered

STMF103R8T6 SPI2 slave receive

Question asked by gamal.youssef on Oct 13, 2011
Latest reply on Oct 14, 2011 by gamal.youssef
Hello,

We are trying to send a 44 byte report over SPI from one STM32F103 to another board.  Our master sends this data out every 5ms, and our slave receives data based on an interrupt. We are experiencing an issue were our last byte from one report is received before the first byte of the second report (so we receive it 5ms later and with the wrong report).
Once the first byte comes in and triggers the interrupt, we loop for the rest of the values rather than having 44 interrupts happen. We also send some bytes during the receiving period, but this part has not been fully implemented/tested yet. Currently, we are using SPI2 with these master configurations:

/** Initializes SPI clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

SPI_InitTypeDef SPI_InitStructure;

/* SPI2 Config -------------------------------------------------------------*/
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_CalculateCRC(SPI2, DISABLE);

/* Enable SPI2 */
SPI_Cmd(SPI2, ENABLE);

//GPIO
GPIO_InitTypeDef GPIO_InitStructure;

/* Configure SPI2 pins: SCK, MOSI, MISO -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; //changed from 2Mhz
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* Configure SPI2 pins: NSS ---------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //was Mode_out_PP
GPIO_Init(GPIOB, &GPIO_InitStructure);


And our slave configurations:
/** Initializes SPI clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

SPI_InitTypeDef SPI_InitStructure;

/* SPI1 Config -------------------------------------------------------------*/
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init(SPI2, &SPI_InitStructure);
SPI_CalculateCRC(SPI2, DISABLE);

/* Enable SPI2 */
SPI_Cmd(SPI2, ENABLE);

//GPIO

GPIO_InitTypeDef GPIO_InitStructure;

/* Configure SPI2 pins: MOSI, MISO -------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* Configure SPI2 pins: NSS ------------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(GPIOB, &GPIO_InitStructure);


Here is out ISR configurations:

NVIC_InitTypeDef NVIC_InitStructure;

// Enable SPI IRQ IRQ Channel -----------------------------------------
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);

We are running into a few odd problems.

1) Occasionally the receiver reads the data as if it was bit-shifted by some amount. When we check the data on the logic analyzer it is coming out correctly from the master. The only way we have seen to fix this is to restart both and try again.

2) This is the more serious problem we are experiencing. We receive the last byte of each report at the beginning of the next report. From our logic analyzer testing, we are sending out the data at the correct time though. so we send:

Master sends:
byte 41 -> byte 42 -> byte 43 -> byte 44 ---------------5ms-------------------- byte 1 -> byte 2

Receiver gets:
byte 41 -> byte42 -> byte 43 ------------------5ms-------------------- byte 44 -> byte 1 -> byte 2

Here is our receiving code:
void rx_only_spi2_isr(void)
{
     SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);
     int cnt=0;

     for(;cnt<44;cnt++)
     {
          if(cnt>34 && cnt<43)
               SPI_I2S_SendData( SPI2, cnt );

          while( SPI_I2S_GetFlagStatus( SPI2, SPI_I2S_FLAG_RXNE ) == RESET );
          spi_buf[cnt] = SPI_I2S_ReceiveData( SPI2 );
     }
     SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
}

Any help would be greatly appreciated.

Outcomes