cancel
Showing results for 
Search instead for 
Did you mean: 

SPI controller on Slave generate RXNE interrupt before last bit was received

stefanschnitzler9
Associate II
Posted on May 26, 2015 at 17:01

Hello,

I want to realize a SPI master slave communication with an STM32F0 Microcontroller. My SPI master use the following configuration:

- Most Significant Bit first

- 8 Bits per Transfer

- Clock is Low when inactive (CPOL = 0)

- Data is Valid on Clock Leading Edge (CPHA = 0)

- Enable Line is Active Low

The SPI frame is 32 bit long. The first transmit byte contains the address and the information if it is an read / write request. I use the CMSIS Libary to configure the SPI controller. In order to capture the first byte I setup my slave as follow:

  SPI_InitTypeDef SPI_InitStructure;

  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

   /* clock to zero when idle */

   SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

   /* The first clock transition is the first data caputure edge */

   SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;

   /* TODO: EAC requirements, SPI speed Master mode is 3MHz */

   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;

   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

   SPI_InitStructure.SPI_NSS  = SPI_NSS_Hard;

   SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;

   SPI_I2S_DeInit(CTRL_SPIx);

   SPI_Init(CTRL_SPIx, &SPI_InitStructure);

   NVIC_EnableIRQ(SPIx_IRQn);

/* Configures the FIFO reception threshold to

    * generate an RXNE interrupt request event if the FIFO

    * level is greater or equal to 1/4.

    */

   SPI_RxFIFOThresholdConfig (CTRL_SPIx, SPI_RxFIFOThreshold_QF );

   /* Enable the TXE and RXNE interrupt */

   SPI_I2S_ITConfig (CTRL_SPIx, SPI_I2S_IT_TXE,  DISABLE);

   SPI_I2S_ITConfig (CTRL_SPIx, SPI_I2S_IT_RXNE, ENABLE);

   SPI_I2S_ITConfig (CTRL_SPIx, SPI_I2S_IT_ERR,  DISABLE);

   /* Enable the SPI peripheral */

   SPI_Cmd(CTRL_SPIx, ENABLE);

In my SPI interrupt I do the following thinks:

  if (CTRL_SPIx->SR & SPI_I2S_FLAG_RXNE)

   {

      uint16_t rx=0;

      DB_PIN1_SET();

      rx = CTRL_SPIx->DR;

      CTRL_SPIx->DR = 0xAA;

      SPI_I2S_ClearFlag  ( CTRL_SPIx,   SPI_I2S_FLAG_RXNE );

      DB_PIN1_RESET();

   }

   else

   {

      SPI_I2S_ClearFlag  ( CTRL_SPIx,   SPI_I2S_FLAG_TXE );

      SPI_I2S_ClearFlag  ( CTRL_SPIx,   SPI_I2S_FLAG_BSY );

      SPI_I2S_ClearFlag  ( CTRL_SPIx,   SPI_I2S_FLAG_OVR );

   }

When I stopped the Processor in the SPI Interrupt the SPI Controller has the following configuration:

CR1: 0x50

CR2: 0x1740

SR: 0x483

DR: 0x0

CRCPR: 0x2

RXCRCR: 0x0

TXCRCR: 0x0

I2SCFGR: 0x0

ISPR: 0x2

The attached file shows the SPI communication. DEBUG_PIN1 is set when enter the SPI interrupt and reset before leave the SPI interrupt.

Thank you every body for your support.

Best regards,

Stefan.

#spi-slave-stm32f0-interrupt
11 REPLIES 11
Posted on May 27, 2015 at 07:05

Harm probably occured before the displayed sequence, after the slave was set up. As RM says,

''It is recommended to enable the SPI slave before the master sends the clock. If not,

undesired data transmission might occur. [...] The SCK signal must be settled at an idle state level corresponding to the selected polarity before the SPI slave is enabled.''

One would expect that NSS high-to-low-transition resets the slave. It may not be the case - the NSS description in RM is messy...

JW
stefanschnitzler9
Associate II
Posted on May 27, 2015 at 09:21

Posted on May 27, 2015 at 11:44

I mean, the SPI slave has ''seen'' one spurious clock before the displayed sequence occured.

I could envisage this might not be seen from outside the chip, e.g. if the GPIO is configured after the SPI got configured/enabled.

JW
stefanschnitzler9
Associate II
Posted on May 28, 2015 at 08:55

The SPI slave is completely configured after startup. All pins are correct configured as AF and this configuration will not be changed during run time. The SPI master is a STM32F0 eval board. When I press the user button it sends an SPI request.

Posted on May 28, 2015 at 09:16

Could you produce a minimal example code exhibiting the problem, on the same eval board? I mean to connect one SPI acting as master to other SPI acting as slave, on the same board, so that the problem could be reproduced e.g. on a DISCOVERY or EVAL board?

JW

lukaskostorz9
Associate II
Posted on May 29, 2015 at 11:35

Hi,

what we did in a first set-up was to connect two STM32051 as master and slave (both on eval boards) to reproduce the problem. As a result we got correct behaviour from master as well as from the slave (Interrupt at 8th byte).

The second set-up was a STM32051 on eval board running as SPI master and a STM32F031 on our prototype board in the role of the SPI slave. The result was an interrupt on the 7th clock edge (7th bit respectively).

You previously assumed a single preceeding clock which would explain the behaviour expected in the second set-up, but the CLK line is fine (see atattched oscilloscope screenshot). By the way, for both set-ups we get the same signal form (nearly same screenshots except the slave's trigger pulse).

Both set ups run on exactly the same code. If you presist I will upload the code..

scope_0.png : F051 vs. F031 (trigger on 7th edge)

scope_1.png : F051 vs. F031 (magnification of previous shot)

scope_4.png : F051 vs. F031 (trigger on 8th edge)

scope_5.png : F051 vs. F031 (magnification of previous shot)

Might this be a bug in the F031 silicon? We run out of ideas..

Regards,

Lukas

________________

Attachments :

scope_0.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0yI&d=%2Fa%2F0X0000000bgQ%2FE0D7uhzRHdApAbpOpr5UTKXN72BDNYSCZQ2zZfUCT9c&asPdf=false

scope_1.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0yD&d=%2Fa%2F0X0000000bgR%2F0Q6AMijXX0NpH6Vmv_s_Neh2xVF27MzVTclrmofv7io&asPdf=false

scope_4.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0y8&d=%2Fa%2F0X0000000bgP%2FojwwRcgMArh39d7PxAUoELRGeA.hOqnbRbgCoELKNhs&asPdf=false

scope_5.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0dv&d=%2Fa%2F0X0000000bgN%2FoO7H5Ry2TQSs4wqNrvGc62wu_eYh3K1XpsSVmFqUDLo&asPdf=false
lukaskostorz9
Associate II
Posted on June 01, 2015 at 09:46

Hi,

I do not see any reason for posting the code unless you provide a reasonable idea why this might help. Even so I do not see the cause in the code. Please read the preceeding post.

Running it on a 31 Eval board, which is not provided as far as I have seen on STM pages would not contribute any benifit. The code which I have run on both set-ups is pretty much the same, unless the IDE (µVision) manipulates it in a severe manner (when I am changing the target from x51 to x31), which I can not believe.

Is there some STM official to have a look on that?

I would appreciate this much.

Regards,

Lukas

Posted on June 01, 2015 at 11:02

AFAIK, the 'F03x silicon is identical to 'F05x silicon, except the former sees substantially less production testing (e.g. tested on lower temperature span) - I'm not ST though. If you suspect they are different in some other way, you always can buy a 'F05x and put it onto your board.

If the substantially same software fails on a different hardware, I'd look at the hardware (i.e. your custom board and the interconnects). I'd look for spikes and ringing on clock and ground. I'd reference a (otherwise well ground-decoupled) scope probe onto the slaves' ground as close as possible to its package/ground pins, and put the tip directly onto the slaves' clock pin.

JW

PS. Try to play with the SPEED setting of the clock pin (and maybe also the MOSI and any other interconnected pin) on the master.

lukaskostorz9
Associate II
Posted on June 08, 2015 at 07:36

Unfortunetaly it is not possible to put a bigger µC on the prototype board.

I had a look on the hardware. I also was looking for a spike that might cause the ''missing'' clock but found no sort of that. Signals were measured directly on the µC pins.

I mean, the µC is also a piece of hardware. Why not persume the error inside?

Is there anyone with a Fx31 who could reproduce the strange behaviour?