2009-10-25 08:22 PM
SPI problem with hardware NSS management
#stm32f0 #metoo-maybe #nss #dma #spi2013-03-07 08:15 AM
2014-10-13 11:12 PM
''-
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.2015-10-02 12:57 AM
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)?2016-02-03 04:19 PM
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 toGPIO_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:
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?