cancel
Showing results for 
Search instead for 
Did you mean: 

SPI problem with hardware NSS management

mudrovc
Associate II
Posted on October 26, 2009 at 04:22

SPI problem with hardware NSS management

#stm32f0 #metoo-maybe #nss #dma #spi
53 REPLIES 53
hamdi_esen
Associate II
Posted on October 14, 2014 at 08:12

''-

   

Point to point SPI communication: NSS OUTPUT pin is not mandatory to be used for a master. This feature is a way for a master to control its slave forcing NSS pin low as soon as it is the master of the communication.''

What makes you think that NSS is not mandatory in point to point SPI?? I need to clock out data from an ADC and it requires periodic CS assertion to start a new conversion and since I want to use DMA in order not to create software overhead I DO NEED hardware NSS signal to go low periodically.  You guys just cant make assumptions about the usage of the protocol. You should have designed it compliant to the SPI standard in the first place.

moritz_noeltner
Associate II
Posted on October 02, 2015 at 09:57

Jup, this summs it up.

And why can't there be a nice way to configure an SPI to be used with multiple slaves (which require different baudrates and phase and polarity)?

valentin
Senior
Posted on February 04, 2016 at 01:19

I think I found a way to do it:

1. configure the SPI in HW NSS Master mode WITHOUT NSSP (no pulse). 2. Manually edit the GPIO pin to

GPIO_PULLUP

(GPIO_Pin_11 in my example).

SPI_HandleTypeDef hspi2;
/* SPI2 init function */
void MX_SPI2_Init(void)
{
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES_RXONLY;
hspi2.Init.DataSize = SPI_DATASIZE_16BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLED;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
hspi2.Init.CRCPolynomial = 7;
hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi2.Init.NSSPMode = SPI_NSS_PULSE_DISABLED;
HAL_SPI_Init(&hspi2);
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
if(hspi->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* Peripheral clock enable */
__SPI2_CLK_ENABLE();
/**SPI2 GPIO Configuration 
PA8 ------> SPI2_SCK
PA9 ------> SPI2_MISO
PA11 ------> SPI2_NSS 
*/
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_MEDIUM;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral interrupt init*/
HAL_NVIC_SetPriority(SPI2_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
}

This is the result: 0690X00000604wyQAA.png Last thing to do is add a Schmitt-Trigger into the CS line directly after the uC. That should do to get HW SPI behaviour conforming to the standard. What do you think?