cancel
Showing results for 
Search instead for 
Did you mean: 

NSS does not wait SPI communication ending

ionutF
Associate III
Posted on May 16, 2016 at 13:52

I have a code in STM32f030 whih communicate with an IC through SPI .

My code is 

  SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,DISABLE);

while(1)

{

ans_status=notArrived;

GPIOB->BRR = GPIO_Pin_12;//select slave

delay(40);

while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET);

SPI_SendData8(SPI2,(u8)(PStartTh+0x80));

while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET);

SPI_SendData8(SPI2,(u8)(0xff));

while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)== RESET);

t=SPI_ReceiveData8(SPI2);

while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_RXNE)== RESET);

t=t+SPI_ReceiveData8(SPI2);

while(SPI_I2S_GetFlagStatus(SPI2,SPI_I2S_FLAG_TXE)==RESET);

SPI_SendData8(SPI2,(u8)(0xff));

delay(40);

GPIOB->BSRR = GPIO_Pin_12;//deselect slave

delay(1000);

}

The device wait for me to send to it 8 bits (the address) , while in this time it does not send anything. After he sends 16 bit data. .While it sends these 16 bit, i send something irelevant (0xff).

The point is that NSS stays low ~ 400 usec while SPI Clock cycles run for 1500usec

SPI is configured as below:

 GPIO_InitTypeDef GPIO_InitStructure;

 SPI_InitTypeDef  SPI_InitStructure;

 GPIO_StructInit(&GPIO_InitStructure);

 /* SPI pin mappings */

 //GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_0);//nss

 GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0);//sck

 GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_0);//miso

 GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0);//mosi

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

 GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;//50MHz

 /* SPI SCK pin configuration */

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;

 GPIO_Init(GPIOB, &GPIO_InitStructure);

 /* SPI  MOSI pin configuration */

 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_15;

 GPIO_Init(GPIOB, &GPIO_InitStructure);

 /* SPI MISO pin configuration */

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;

 GPIO_Init(GPIOB, &GPIO_InitStructure);

 /* SPI NSS pin configuration */

/*  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

 GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

 GPIO_Init(GPIOB, &GPIO_InitStructure);*/

 /* SPI configuration -------------------------------------------------------*/

 SPI_I2S_DeInit(SPI2);

 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

 //SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;

 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

 SPI_InitStructure.SPI_CRCPolynomial = 7;

 /* Initializes the SPI communication */

 SPI_Init(SPI2, &SPI_InitStructure);

 SPI_RxFIFOThresholdConfig(SPI2,SPI_RxFIFOThreshold_HF);

 SPI_NSSPulseModeCmd(SPI2,DISABLE);

 SPI_SSOutputCmd(SPI2,DISABLE);

 SPI_I2S_ITConfig(SPI2,SPI_I2S_IT_RXNE,ENABLE);

 SPI_Cmd(SPI2,DISABLE);

 delay(10000);
2 REPLIES 2
Posted on May 16, 2016 at 14:11

You must pair the send/receive as only the send generates clocks, and receive simple reads a register. You must also wait for the receive to complete rather than the TX holding buffer being empty, which occurs about the time the FIRST bit hits the bus, not the LAST.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
megahercas6
Senior
Posted on May 19, 2016 at 13:02

Indeed, just like he said.

this is proper way to read/write to SPI ( you can use dummy read or dummy write if you want only one communication direction, but SPI must be configured for duplex master

uint16_t Read_Write_DAC(uint16_t data)
{
GPIOB->BSRRH=GPIO_Pin_1; //CS low
while(((SPI1->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY));
while(!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE)); 
SPI1->DR=data;
while(((SPI1->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE));
GPIOB->BSRRL=GPIO_Pin_1; //CS high
return ((SPI1->DR)>>1);
}