cancel
Showing results for 
Search instead for 
Did you mean: 

stm32L476RG SPI read data from FRAM occurred error .

Lucky Dog
Associate III

The FRAM chip I'm using is cypress.For details, here's a screenshot of my chat with Cypress.Thank you very much.

1 ACCEPTED SOLUTION

Accepted Solutions

Hello, my problem has been solved. I saw one of your answers in the forum, so I didn't use the online debugging method to observe variables. I think maybe STLINK is consuming my CPU resources and my system clock frequency is only 2MHZ. Thank you very much .0693W00000DlyURQAZ.png

View solution in original post

5 REPLIES 5

You've provided very little detail and specifics here.

Attach a minimal example that demonstrates the interaction and illustrates the failure.

Try different clock phase for inbound data.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Lucky Dog
Associate III

1.I have tried different clock phases.FRAM only supports modes 0 and 3.It doesn't solve the problem.

2.I read data from SPI in two different ways. The first is DMA read,as shown in figure 1.The second is query read,as shown in figure 2. Both of these different approaches can lead to errors.

3.My experimental condition was to write 0 to 255 to FRAM and then read the 256 bytes from FRAM every few milliseconds. When repeated hundreds of times, an error occurs.

4.I have tried to read data using SPI emulation and have no such problem.

5.I present the key code for both approaches below

​ Figure 1

​ Figure 2

Query way:

uint8_t SPI_Receive(void)

{

  uint16_t i,retry = 0;

  

  SPI_Enable();

  SPI_CS_Select();

  

  for(i=0;i<4;i++)   //transfer opcode and address

  {  

    *((__IO uint8_t *)&SPI1->DR) = spi_transmission.txBuff[i];  

    while((SPI1->SR & SPI_SR_BSY) != 0U)

    {

     retry++;

     if(retry > 0xFFF)

      return 1;

    }

    retry = 0;

   

  }

   

  while(LL_SPI_IsActiveFlag_BSY(SPI1));   

   

  while((SPI1->SR & SPI_SR_FRLVL) != 0x00 )       //empty RxFIFO

  {

     SPI1->DR;   

  }                 

     

  for(i=0;i<spi_transmission.rxLength;i++)   //  In order to generate read back clock 

  {                  

    *((__IO uint8_t *)&SPI1->DR) = 0x00; 

       

    while((SPI1->SR & SPI_SR_BSY) == SPI_SR_BSY)

    {

     retry++;

     if(retry > 0xFFF)

      return 1;

    }

    retry = 0;     

     

    spi_transmission.rxBuff[i] = LL_SPI_ReceiveData8(SPI1);

       

  }

           

  SPI_CS_Deselect();

  SPI_Disable();

  return 0;

}

DMA way:

uint8_t Cy15b108qi_Read_Memory_DMA(uint32_t address,uint16_t datalen)

 uint8_t retry = 0;

 uint8_t tempdata[4];

  

 tempdata[0] = READ ;

 tempdata[1] = (address >> 16) & 0x0F;

 tempdata[2] = (address >> 8) & 0xFF ;

 tempdata[3] = address & 0xFF;

 spi_transmission.rxLength = datalen + 1; 

 spi_transmission.txLength = datalen ;

  

 memset(spi_transmission.txBuff,0,datalen);    //to Produce the clock ,Not Essential

  

 SPI_Enable();

 SPI_CS_Select(); 

  

 for(uint16_t i=0;i<4;i++)   //transfer opcode and address

 {  

   *((__IO uint8_t *)&SPI1->DR) = tempdata[i];  

   while((SPI1->SR & SPI_SR_BSY) == SPI_SR_BSY)

   {

    retry++;

    if(retry > 0xFE)

     return 1;

   }

   retry = 0;      

 }   

    

 while((SPI1->SR & SPI_SR_FRLVL) != 0x00)      //Empty RXFIFO

 {

   SPI1->DR;  

 }

  

 DMA1_Channel2->CNDTR = (DMA1_Channel2->CNDTR & (~DMA_CNDTR_NDT)) | spi_transmission.rxLength ;

 DMA1_Channel3->CNDTR = (DMA1_Channel3->CNDTR & (~DMA_CNDTR_NDT)) | spi_transmission.txLength ;

 SPI1->CR2 |= (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);      // a DMA request is generated whenever the RXNE or TXE flag is set       

 DMA1_Channel2->CCR |= (DMA_CCR_TCIE |DMA_CCR_EN);

 DMA1_Channel3->CCR |= DMA_CCR_EN;

  

 return 0;

}

void DMA1_Channel2_IRQHandler(void)          //Rx

{

  

 if((DMA1->ISR & DMA_ISR_GIF2) == DMA_ISR_GIF2)

 {

   

  DMA1->IFCR |= DMA_IFCR_CGIF2;

     

  SPI_CS_Deselect();

  SPI_Disable();

    

  DMA1_Channel2->CCR &= ~(DMA_CCR_EN |DMA_CCR_TCIE);

  DMA1_Channel3->CCR &= ~DMA_CCR_EN;  

   

  SPI1->CR2 &= ~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); 

  SPI1->CR1 &= (~SPI_CR1_CRCEN); 

  spi_transmission.Rx_complete = 1;

 }

 if((DMA1->ISR & DMA_ISR_TEIF2) == DMA_ISR_TEIF2)

 {

  

  DMA1_Channel2->CCR &= ~DMA_CCR_EN;

 }

}

Thank you very much for your reply.

0693W00000DlgR0QAJ.png0693W00000DlgQqQAJ.png

I wonder if this is related to the system clock. My system clock is 2MHZ. I have also tried an 80MHZ system clock and errors are less frequent, but they are not inevitable. I look forward to your reply. Thank you.

Hello, my problem has been solved. I saw one of your answers in the forum, so I didn't use the online debugging method to observe variables. I think maybe STLINK is consuming my CPU resources and my system clock frequency is only 2MHZ. Thank you very much .0693W00000DlyURQAZ.png