cancel
Showing results for 
Search instead for 
Did you mean: 

SPI communication with LAN9252 only works the first time

kaiseong
Associate

Hi everyone. I am trying to communicate with a board called EVB-LAN9252-SPI via SPI, and I am only getting the datasheet-correct result for the first SPI request.
If I send 0x03 and then 0x0050, I should get 0x92520001. Right now, I only get 0x92520001 for the first reception, and after that, I get 0x00480000, 0x00440000, and 0x00400000, which is the same value as 0x00400000. What is wrong with my setup?

 

The code is as follows.

 

void spi_wirte(void)
{
    uint8_t tx[3]={0x03, 0x00, 0x50};
    uint8_t rx[4]={0,};
    while(1)
    {
         HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
         HAL_SPI_Transmit(&hspi1, tx,3,100);
         HAL_SPI_Receive(&hspi1, rx,4,100);
         HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);
         printf("data :");
         for (int i=0;i<4;i++)
             printf("%02X",rx[i]);
         printf("\n");
         HAL_Delay(10);
     }
}

 

Thank you.

 

3 REPLIES 3
Andrew Neil
Evangelist III

@kaiseong wrote:

Hi everyone. I am trying to communicate with a board called EVB-LAN9252-SPI


You mean this: https://www.microchip.com/en-us/development-tool/evb-lan9252-spi ?

So this chip: https://www.microchip.com/en-us/product/lan9252 

Have you looked at the SPI lines with a logic analyser to see what's actually happening on the wires?

Does it match the datasheet specification:

AndrewNeil_1-1727859181966.png

 

         HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET);
         HAL_SPI_Transmit(&hspi1, tx,3,100);
         HAL_SPI_Receive(&hspi1, rx,4,100);
         printf("data :");
         for (int i=0;i<4;i++)
             printf("%02X",rx[i]);
         printf("\n");
         HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET);

Doing a separate HAL_SPI_Transmit and HAL_SPI_Receive is going to leave a gap between sending the address and reading the data - does the chip mind that?

Also, why wait for the print loop to finish before releasing SCS# ?

 

Please see the posting tips for how to properly post source code:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

 

 

Thank you for your response, and I apologize for the shortcomings in my previous post.
I have corrected the code as you advised.

Firstly, I could not test the logic you mentioned as it is not implemented in the current setup.

The reason why printf was executed before deselecting the CS pin is because I was modifying the code while testing. However, even after moving the printf statement to after the CS pin deselection, the symptoms remained the same.

The datasheet has been confirmed by the chip manufacturer, so the specifications match. Additionally, when I used spi.write() in Keil Studio as shown in the code below, it worked correctly.

int main() {
    serial.baud(115200);
    ss=1;
    spi.format(8,0);
    spi.frequency(20000000);
    printf("reset\n");
  while(1) {
      ss=0;
       spi.write(0x03);
       spi.write(0x0);
       spi.write(0x50);
       rdata =  spi.write(0x00);
       rdata |= spi.write(0x00)<<8;
       rdata |= spi.write(0x00)<<16;
       rdata |= spi.write(0x00)<<24;
      ss=1;
       printf("ID_REV: 0x%X\n", rdata);
    wait(0.1);
  }
}

I believe your suggestion, "Doing a separate HAL_SPI_Transmit and HAL_SPI_Receive is going to leave a gap between sending the address and reading the data - does the chip mind that?" is the most likely cause of the issue. I'll look into it.


Thank you.


@kaiseong wrote:

The datasheet has been confirmed by the chip manufacturer, so the specifications match


That wasn't the question.

The question was whether what's actually happening in your system - on your actual SPI wires - matches the specifications in the datasheet.

You need to check that.

 


@kaiseong wrote:

when I used spi.write() in Keil Studio as shown in the code below, it worked correctly.


So get a logic analyser trace of that working case - compare & contrast with your non-working case...