cancel
Showing results for 
Search instead for 
Did you mean: 

spi problem

karan
Associate III
Posted on July 06, 2015 at 14:37

i am using stm32f030c8t6 device .i communicate with external memory ic on spi bus.i am using stmcube32 and mdk-5.

for testing purpose i read its id using spi.i am using spi2. at first am not able to generate clock for that i spent nearly whole day and last found that hal init function dose not initialize cr1 resister so i manual add this(hspi2.Instance->CR1|=0x00000040;).

now able to get clock.here is my function

uint8_t GetSrrialSPINVRAM(SPI_HandleTypeDef *deviceFd,uint8_t *rbuff)

{

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_RESET);

uint32_t result;

uint8_t spiBuff[2];

uint16_t junkbuff[10];

spiBuff[0]=0x9F;

//HAL_SPI_Receive_IT(deviceFd,rbuff,5);

result=HAL_SPI_Transmit(deviceFd,spiBuff,1,15);

if(result!=HAL_OK)

return 0;

//HAL_SPI_FlushRxFifo(deviceFd);

//HAL_SPI_FlushRxFifo(deviceFd);

//osDelay(1);

//check=deviceFd->Instance->DR;

//HAL_SPI_Receive(deviceFd,junkbuff,1,5);

//HAL_SPI_Receive(deviceFd,rbuff,1,5);

//HAL_SPI_Receive_IT(deviceFd,rbuff,4);

//while(deviceFd->State !=HAL_SPI_STATE_READY);

//while((deviceFd->Instance->SR & SPI_FLAG_FRLVL)!=  SPI_FRLVL_EMPTY)

//{

// junkbuff[0]=deviceFd->Instance->DR;

//}

//junkbuff[1]=deviceFd->Instance->DR;

//junkbuff[2]=deviceFd->Instance->DR;

result=HAL_SPI_Receive(deviceFd,rbuff,4,15);

check=result;

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_12,GPIO_PIN_SET);

if(result!=HAL_OK)

return 0;

return 1;

}

i am expecting reply 0x0681c8a0 but i am getting 0x000681c8 and when read 5 byte got

 0x000681c8a0 .so receiving one extra byte at beginning. after searching some time on net i found that its due to dummy receive while transmitting.so i try to flush rxfifo after tx.but when i try flush instruction random data received every time so please guide me whats wrong

here is command information

  i use pb12 as gpio out put which is connected to ss of external ic and data size is 8 bit .

here is init fun

  hspi2.Instance = SPI2;

  hspi2.Init.Mode = SPI_MODE_MASTER;

  hspi2.Init.Direction = SPI_DIRECTION_2LINES;

  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;

  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;

  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;

  hspi2.Init.NSS = SPI_NSS_SOFT;

  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 = 10;

  hspi2.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

  hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLED;

  HAL_SPI_Init(&hspi2);

hspi2.Instance->CR1|=0x00000040;

and source freq is 48mz

5 REPLIES 5
jpeacock
Associate III
Posted on July 06, 2015 at 20:02

Remember that SPI is always bidirectional, even if you don't want the data you have to do something with it.  When you send a command string you have to read back the data shifted in while shifting out each byte of the command.

Whenever you start an SPI bus operation make sure the receive buffer is empty before shifting out the first byte.  Always clear the receiver before shifting out the next command byte.

If you use DMA this can be done automatically by setting up both rx and tx DMA channels.  When sending data the receive channel always goes to the same location, no memory increment, so the data is thrown away.  When receiving data the transmit DMA channel always shifts out from the same location, since you only need a dummy output to generate a clock.  And if you use DMA, make sure RX always has a higher DMA priority than TX so the receiver will stay cleared.

Some SPI peripherals require a ''dummy'' byte in order to process the command internally before shifting in/out data.  The part datasheet should show if you need to allow for this.

  Jack Peacock
karan
Associate III
Posted on July 09, 2015 at 14:11

yes but when i flush rxfifo after tx than there should be no problem but still not working.

and i am not able to transmit or receive through dma .i set dma channel setting in stm32cube and enable interrupt.

jpeacock
Associate III
Posted on July 09, 2015 at 21:43

If your SPI peripheral requires a one byte delay for internal operation then shift out an extra byte of zeroes at the end to read in the last byte.   From your description it is working but you didn't send out enough TX clocks to get all the data.

For SPI DMA you have to use both TX and RX DMA channels since it's bi-directional data transfer.  If you do TX only you get an RX buffer overflow error.

  Jack Peacock

karan
Associate III
Posted on July 10, 2015 at 07:36

thanks for reply.last byte is not missed what happen is,

first i send 1 byte read command so 1 garbage byte is received in fifo

then i write flush rxfifo instruction

now i use hal_spi_receive api with data size 4.so it call txrx function.and as datasize>1.it select 16 bit allignment.and as there is already one byte in fifo(garbage)+one original byte received so rxne is raised and one word is read out with 1byte garbage.now tx and rx count is decremented by 2.now furter 2 byte transmitted and received in fifo.but due to allinment rxne is generated before 1 byte prior.so final byte is received in fifo but not red out by api.so here my problem is flush fifo api not working

salekg
Associate
Posted on December 27, 2015 at 04:11

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6WZ&d=%2Fa%2F0X0000000bpv%2FUvpWKcnZTFt6xTmsuDJsbyZqIR18Eq6s0_j7GiE2KZs&asPdf=false