cancel
Showing results for 
Search instead for 
Did you mean: 

[SOLVED]I'm having problems with SPI NSS pin toggle

IvanG
Associate II

Hi everyone, I'm using SMT32L073RZ as my MCU and it has connected through SPI a flash memory (microchip's SST25VF016B).

So the connection is as follows:

PA5   ------> SPI1_SCK

PA6   ------> SPI1_MISO

PA4   ------> SPI1_NSS

PA7   ------> SPI1_MOSI)

PA0   ------> WP (write protection)

PB5   ------> HOLD

WP and HOLD are both initialized as PIN_NO_PULL and with value 1(pulled up)

As for the SPI1 pins are all initialized by STM32CubeMX as GPIO_AF0_SPI1:

/* SPI1 clock enable */
    __HAL_RCC_SPI1_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**SPI1 GPIO Configuration    
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA4     ------> SPI1_NSS
    PA7     ------> SPI1_MOSI 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_4|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

SPI is also initialized by STM32CubeMX as follows:

void MX_SPI1_Init(void)
{
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    printf("Error HAL_SPI_Init 1 init\r\n");
  }
}

The problem comes when I try to make this0690X000009jzzLQAQ.png

CE#(NSS) must be driven low before the EWSR (enable write status register) instruction is entered and must be driven high before the EWSR instruction is executed.

CE#(NSS) must be driven low before the command sequence of the WRSR (write status register) instruction is entered and driven high before the WRSR instruction is executed.

Here is the code in wich i try to make that happen:

void WriteStatusRegister(bool block)
{
	InitFlashSPI();
	uint8_t data[1];
	data[0] = EWSR;
	uint8_t res[sizeof(data)];
	memset(res, 0, sizeof(data));
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);		//NSS 	= 0
	HAL_SPI_TransmitReceive(&hspi1, data, res, sizeof(data), HAL_MAX_DELAY);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);		//NSS 	= 1
	uint8_t write[2];
	write[0] = WRSR;
	if (block == true)
	{
		write[1] = 0x1C;
	}
	else
	{
		write[1] = 0x02;
	}
	uint8_t resw[sizeof(write)];
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);		//NSS 	= 0
	HAL_SPI_TransmitReceive(&hspi1, write, resw, sizeof(write), HAL_MAX_DELAY);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);		//NSS 	= 1
	DeInitFlashSPI();
}

But looking at the digital levels with a logic analizer this is what the result is:

0690X000009k04GQAQ.png

As you can see, SPI-ENABLE(NSS) is driven low before the start of the first byte (0x50) and then stays that way for the rest of the communication, making the EWSR command invalid.

I'll appreciate any comments, thanks.

1 REPLY 1
IvanG
Associate II

So, I kinda find something to keep going..

The STM32CubeMx intialize the "hspi1.Init.NSS" as "SPI_NSS_HARD_OUTPUT" wich makes the NSS pin be driven by the firmware in it's self. And this made the HAL_GPIO_WritePin command not work.

So I ended up changing a few configurations:

First I change the configuration of the pin itself to be GPIO_MODE_OUTPUT_PP instead of GPIO_MODE_AF_PP.

__HAL_RCC_SPI1_CLK_ENABLE();
  
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**SPI1 GPIO Configuration    
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA4     ------> SPI1_NSS
    PA7     ------> SPI1_MOSI 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
		
		// PA4 control
		GPIO_InitStruct.Pin  = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

Then changed "hspi1.Init.NSS" from "SPI_NSS_HARD_OUTPUT" to:

hspi1.Init.NSS = SPI_NSS_SOFT;

This made the signals change whenever the HAL_GPIO_WritePin was called. It also made the logic analyzer not read the SPI signals properly, but thats just bad for the logic analyzer.

I still have some work to do on the firmware, so I'll leave this thread open for now..