I read somewhere that NSS is disabled as long as the SPI master is turned on and lights up again if the SPI master is disabled. I tried this using the HAL library (Cube / CubeMX) from ST using STM32L476 and polling SPI1. Initialization before and de-initialization after the transmission did NOT set Pin NSS - but it took a long time:
Init structure:
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_HIGH; hspi1.Init.CLKPhase = SPI_PHASE_2EDGE; hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT; hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 7; hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE; hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
Transmission Sequence:
HAL_SPI_Init( &hspi1 ); HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec; while( hspi1.State == HAL_SPI_STATE_BUSY ); // wait for xmission complete HAL_SPI_DeInit( &hspi1 );
So, I decided to establish contact manually using GPIO (using SPI_NSS_SOFT in init):
HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_RESET ); // NSS1 low HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec; while( hspi1.State == HAL_SPI_STATE_BUSY ); // wait xmission complete HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_SET ); // NSS1 high
I used blocking transmission (without DMA or interruption) because it was fast enough and no other tasks were expected. Installing DMA was unacceptably longer to send only 24 bytes at a frequency of 20 MHz. That would be an acceptable alternative.
As far as I can see in the STM32L4xx instruction manual in chapter 38.4.12 / 13, automatic NSS becomes high after each byte / word transmission and therefore is not suitable for longer streams that keep the NSS low for the entire transmission.
source share