2020-03-26 01:53 AM
Hi,
project details:
I have understand that in the master (I am using a FPGA) I must select low or high the CS to select the slave (STM32F411VE board), but what about the slave?, do I need to implement something like this to receive the data?
//first way
while(1)
{
if (HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1) == 0) //CS pin
{
HAL_SPI_TransmitReceive(&hspi5,txbuffer,rxbuffer, 12, 5000);
}
}
or the function transmitreceive detects internally if the CS is low to start the communication?, I mean, receive the data just doing this:
//second way
while(1)
{
HAL_SPI_TransmitReceive(&hspi5,txbuffer,rxbuffer, 12, 5000);
}
I have this query because I am doing tests (second way) in the slave but always receive data when I connect the CS pin to GND or 3.3V, and in the TransmitReceive function I dont´t find any line of code that checks if CS is enabled or disabled to start the tx/rx of data
thanks
2020-03-26 02:24 AM
Use the SPI_NSS pin configured in input mode - let the H/W do it for you :)
2020-03-26 02:30 AM
Hi, I have configured the NSS in this way, so you tell me that when the nss is configured by hardware the function detects it automatically?, I thought this was only when I configure nss in software mode (disabled in cubemx)
2020-03-26 02:59 AM
void SPI1_IRQHandler(void)
{
/* Check OVR/UDR flag value in ISR register */
if(LL_SPI_IsActiveFlag_OVR(SPI1) || LL_SPI_IsActiveFlag_UDR(SPI1))
{
SET_BIT(SPI1->IFCR, SPI_IFCR_OVRC); //clear over and under run errors
SET_BIT(SPI1->IFCR, SPI_IFCR_UDRC);
return;
}
/* Check RXP flag value in ISR register */
if(LL_SPI_IsActiveFlag_RXP(SPI1) && LL_SPI_IsEnabledIT_RXP(SPI1))
{
/* Call function Reception Callback */
SPIRxBuf[SPIRxBufHead] = LL_SPI_ReceiveData8(SPI1); // store the byte in the ring buffer
SPIRxBufHead = (SPIRxBufHead + 1) % CONSOLE_RX_BUF_SIZE; // advance the head of the queue
return;
}
/* Check EOT flag value in ISR register */
if(LL_SPI_IsActiveFlag_EOT(SPI1) && LL_SPI_IsEnabledIT_EOT(SPI1))
{
/* Call function Reception Callback */
SET_BIT(SPI1->IFCR, SPI_IFCR_EOTC);
LL_SPI_SetTransferSize(SPI1, 1024);
return;
}
void GPIOPins_SPI1_Config(void)
{
/* (1) Enables GPIO clock and configures the SPI1 pins *******************/
/* Enable the peripherals clocks of GPIOs */
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOB);
LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_GPIOA);
/* SPI1 SCK GPIO pin configuration*/
GPIO_InitStruct.Pin = SPIx_MASTER_SCK_PIN;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Pull = LL_GPIO_PULL_DOWN;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = SPIx_MASTER_SCK_AF;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI1 MISO GPIO pin configuration*/
GPIO_InitStruct.Pin = SPIx_MASTER_MISO_PIN;
GPIO_InitStruct.Alternate = SPIx_MASTER_MISO_AF;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI1 MOSI GPIO pin configuration*/
GPIO_InitStruct.Pin = SPIx_MASTER_MOSI_PIN;
GPIO_InitStruct.Alternate = SPIx_MASTER_MOSI_AF;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* SPI1 NSS GPIO pin configuration*/
GPIO_InitStruct.Pin = LL_GPIO_PIN_4;
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* (2) Configure NVIC for SPI1 transfer complete/error interrupts **********/
/* Set priority for SPI1_IRQn */
NVIC_SetPriority(SPI1_IRQn,0);
/* Enable SPI1_IRQn */
NVIC_EnableIRQ(SPI1_IRQn);
}
void SPI1_Config (void)
{
/* Configure SPI SLAVE *****************************************************/
/* Enable SPI1 Clock */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
/* Configure the SPI1 parameters */
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
SPI_InitStruct.TransferDirection = LL_SPI_SIMPLEX_RX;
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
SPI_InitStruct.NSS = LL_SPI_NSS_HARD_INPUT;
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
SPI_InitStruct.Mode = LL_SPI_MODE_SLAVE;
LL_SPI_Init(SPI1, &SPI_InitStruct);
/* Lock GPIO for master to avoid glitches on the clock output */
LL_SPI_DisableGPIOControl(SPI1);
LL_SPI_DisableMasterRxAutoSuspend(SPI1);
/* Set number of date to transmit */
LL_SPI_SetTransferSize(SPI1, 1024);
/* Enable SPI1 */
LL_SPI_Enable(SPI1);
/* Enable TXP Interrupt */
// LL_SPI_EnableIT_TXP(SPI1);
/* Enable RXP Interrupt */
LL_SPI_EnableIT_RXP(SPI1);
/* Enable SPI Errors Interrupt */
LL_SPI_EnableIT_CRCERR(SPI1);
LL_SPI_EnableIT_UDR(SPI1);
LL_SPI_EnableIT_OVR(SPI1);
LL_SPI_EnableIT_EOT(SPI1);
}
Certainly seems to work. I'm using SPI in receive simplex mode with interrupts buffering the incoming data into a circular buffer and when I disconnect NSS the receive stops as you would expect.