cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Multi-master NSS Setup

STM32Freakz
Associate II

Hello

Im trying to implement stm32 spi multi-master function on a stm32f765 according to the below presentation

0693W000003QsuWQAS.png

I keep getting MODF error when transmitting as a master, that would indicate that the slave sets the masters NSS pin low. Even if I set the NSS pin permantently high, by hooking it to a 3,3v pin , I get the same error!

below is my setup:

--------MSP SETUP--------------------------------------
GPIO_InitStruct.Pin = SPI_CS_Pin;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
    GPIO_InitStruct.Mode        = GPIO_MODE_INPUT | GPIO_MODE_IT_RISING;
    GPIO_InitStruct.Pull      =  GPIO_PULLUP;
    HAL_GPIO_Init(SPI_CS_GPIO_Port, &GPIO_InitStruct);
 
    // SPI master com trigger GPIO pin configuration
    GPIO_InitStruct.Pin = SPI_MASTER_TRIG_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP ;
    HAL_GPIO_Init(SPI_MASTER_TRIG_Port, &GPIO_InitStruct);
--------MSP SETUP--------------------------------------
 
------------SPI Handle setup--------------------------
 
static void setupSPIbaseStruct(SPI_HandleTypeDef *pSpiHandle, uint32_t mode)
{
 pSpiHandle->Instance               = SPI2;
  if (mode == SPI_MODE_MASTER) {
    pSpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
  }else{
    pSpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;
  }
  pSpiHandle->Init.Direction         = SPI_DIRECTION_2LINES;
  pSpiHandle->Init.CLKPhase          = SPI_PHASE_2EDGE;
  pSpiHandle->Init.CLKPolarity       = SPI_POLARITY_HIGH;
  pSpiHandle->Init.DataSize          = SPI_DATASIZE_8BIT;
  pSpiHandle->Init.FirstBit          = SPI_FIRSTBIT_MSB;
  pSpiHandle->Init.TIMode            = SPI_TIMODE_DISABLE;
  pSpiHandle->Init.CRCCalculation    = SPI_CRCCALCULATION_ENABLE;
  pSpiHandle->Init.CRCPolynomial     = 7;
  pSpiHandle->Init.NSSPMode          = SPI_NSS_PULSE_DISABLED;
  pSpiHandle->Init.NSS               = SPI_NSS_HARD_INPUT;
  pSpiHandle->Init.Mode              = mode ;
}
------------SPI Handle setup--------------------------

what Im I doing wrong?

10 REPLIES 10

Read out and check/post content of SPI and relevant GPIO registers.

JW

Thank you for reply

A read out of NSS pin inside of error callback says pin is high, contrary to what should have triggered the error in question(MODF) modf(1) bit is set in Spihandle.ErrorCode

CR1 : 1010000100110011 / 0xa133

CR2: 1011100000000 / 0x1700

SR : 10 / 0x2

ErrorCode: 1 / 0x1

GPIO port IDR = 1

I don´t know if there´s any other relevant information?

Which pin is used for NSS? How is that pin's MODER and AFR set in GPIO?

JW

The setup is the one I pasted in the code, the SPI_CS_Pin refers to GPIO_PIN_9 and SPI_CS_GPIO_Port to port GPIOB

and alternate function in use is AF5 according to the table below0693W000003QzClQAK.png

  1. GPIO_InitStruct.Pin = SPI_CS_Pin;
  2. GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
  3. GPIO_InitStruct.Mode = GPIO_MODE_INPUT | GPIO_MODE_IT_RISING;
  4. GPIO_InitStruct.Pull = GPIO_PULLUP;
  5. HAL_GPIO_Init(SPI_CS_GPIO_Port, &GPIO_InitStruct);

I don't use Cube/HAL and don't understand it.

Read out and check/post the relevant register's content.

You want the pin to be set to AF in GPIO_MODER, and to proper AF in GPIO_AFR. My guess is, that this:

> GPIO_InitStruct.Mode = GPIO_MODE_INPUT | GPIO_MODE_IT_RISING;

does not do that.

JW

So i guess we are on different sides of it, I can´t fully interpret the content of those registers:

GPIOx->MODER =  0xaaa06aa0  / 10101010101000000110101010100000
 
AFR = 0x40020020  /  1000000000000100000010000100000
       AFR[0] = 0xa666900  /  1010011001100110100100000000
 
       AFR[1] = 0x55bbbb00  /  1010101101110111011101100000000

What am I looking for? Thank you for helping!

EDIT: I see now that because Im setting Mode to GPIO_MODE_INPUT, the step where Alternate function is set is skipped. The reason why I set it to GPIO_MODE_INPUT and not GPIO_MODE_AF_PP was that I got strange behavior with the pin getting set half way (~2,2V / floating behavior), which disappeared when I set it to input.

How did you read that out? Did you use the debugger's register view?

AFR[1] = 0x40020020

This is suspiciously address of GPIOA->AFR[0].

JW

I updated the answer just before your post

I simply had a break point inside the setup function after the pin config

If your referring to the SFR view, that view does not show the GPIO registers:

0693W000003QzqMQAS.png

> What am I looking for?

We are talking about PB9, so you want to look in MODER at bits 18 and 19 (i.e. 9*2 and 9*2+1 - two bits per pin are used), they are 0b00 which means Input, and are supposed to be 0b10 for AF. Then we would be looking at bits 4 to 9 in AFR[1] (4 bits per pin, that is 32 bits for pins PB0..PB7 in AFR[0] and 32 bits for pins PB8..PB15 in AFR[1].

Having no pin set to AF corresponding to the SPI2_NSS means, that internally that node is set to 0 - which immediately after enabling SPI switches it to slave mode.

> The reason why I set it to GPIO_MODE_INPUT and not GPIO_MODE_AF_PP was that I got strange behavior with the pin getting set half way (~2,2V / floating behavior), which disappeared when I set it to input.

I don't understand. If the PB9 is set as AF in MODER and AF5 in AFR[1], and SPI module is set so that NSS is input (i.e. SPI_CR2.SSOE=0), the PB9 pin works in exactly the same way as when it's set to Input. If not, some of those 3 things are not set in that way.

Do you have a pullup on that pin?

JW