cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Problems

markmark9121
Associate II
Posted on August 16, 2013 at 05:25

I am using the STM32F103 to interface with a FPGA over SPI and I am having the following issue.

When I am reading a 32 bit variable from the FPGA (4 bytes) it seems to work fine with the first communication and then have a problem with the remaining time I read it.

It looks like it is still using data from the previous read in to the new one. If I reset the STM32 in debug (not doing anything to the FPGA) it will read correctly for 1 time again.

Here is an example read:

Data sent is 56787

First read : 00 00 DD C0 (correct)

Second read: C0 00 DD C0 (not right)

My SPI code is the following

uint32_t FPGASendVelocity(uint32_t velocityCommand )

{

  uint32_t i;

  uint32_t remaining = 0;

  uint8_t src_addr[5];

  uint8_t inBuff[5] = {0,0,0,0,0};

  uint8_t temp1, temp2, temp3, temp4;

  src_addr[0] = 2; // Send the set velocity command first

  // Send the 24 bit value

  src_addr[1] = velocityCommand >> 16; src_addr[2] = velocityCommand >> 8; src_addr[3] = velocityCommand;

  GPIO_WriteBit(GPIOC, GPIO_Pin_6, 0); // Set SSEL pin low

  for(delay=0; delay<SPIDELAY; delay++); // Delay due to timing issuse?

  for ( i = 0; i < 4; i++ )

  {

      // Data out

      while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

      SPI_I2S_SendData(SPI1, src_addr[i]);

      // Data in

      while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

      inBuff[i] = SPI_I2S_ReceiveData(SPI1);

      for(delay=0; delay<SPIDELAY; delay++);

  }

  GPIO_WriteBit(GPIOC, GPIO_Pin_6, 1); // Set SSEL pin high

  remaining |= (inBuff[0] << 24);

  remaining |= (inBuff[1] << 16);

  remaining |= (inBuff[2] << 8);

  remaining |= (inBuff[3]);

  return remaining;

}

Any help would be appreciated

Dave
4 REPLIES 4
markmark9121
Associate II
Posted on August 16, 2013 at 22:57

My Config is as follows:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_SPI1, ENABLE);

void SPI_Configuration(void)

{

    SPI_InitTypeDef SPI_InitStructure;

    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_Low;

    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;

    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

    SPI_Init(SPI1, &SPI_InitStructure);

    SPI_Cmd(SPI1, ENABLE);

}

  /* Configure SPI1 pins: SCK, MISO and MOSI -------------------------------*/

  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // SSEL Pin

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

Posted on August 16, 2013 at 23:25

I'd probably do two things here:

Make sure I got RXNE clear before I started.

Review two of these 32-bit transactions on a logic analyzer or scope, to better understand what was happening on the pins.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
markmark9121
Associate II
Posted on August 17, 2013 at 17:36

Well I took your advice and I think the problem is in my FPGA code.

Checking for RXNE first did not fix the problem so I attached the scope and found the following.

When I reset the STM32 it must toggle the chip select pin a few times and properly reset the send registers in the FPGA, after the reset the scope send looks good and the second sent looks like the data that I am getting on the STM32.

Here it is after the reset:

0690X00000602mbQAA.jpg

And here is the second transfer:

0690X00000602pKQAQ.jpg
markmark9121
Associate II
Posted on August 17, 2013 at 17:42

I added this to the beginning of the send / receive function at it seems to have ''fixed'' the problem

GPIO_WriteBit(GPIOC, GPIO_Pin_6, 0); // Set SSEL pin low

for(delay=0; delay<20; delay++);

GPIO_WriteBit(GPIOC, GPIO_Pin_6, 1); // Set SSEL pin high

for(delay=0; delay<20; delay++);

So it looks like I need to do a proper code fix on the FPGA

Thanks for the help

Dave