cancel
Showing results for 
Search instead for 
Did you mean: 

How do I know if the SPI is correctly working, if I can only check on the master's board?

JunseokOh
Associate II

I have an STM32F429ZI Nucleo board (for SPI master and UART to check everything's working alright) and an EVB-LAN9252-SPI board(for SPI slave).

I have to check if the SPI is correctly working, but it seems that I can't debug or check on the slave's side.

Shown below is the test code I worked on the STM32F429ZI Nucleo board to check if the SPI is working correctly. SPI1 and SPI4 is configured in one board.

  while (k < 32)
  {
    HAL_UART_Transmit(&huart4, &SPI1_Buffer_Tx[k], 1, 100);
    k++;
  }
  k = 0;
 
  while (k < 32)
  {
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_RESET); // this GPIO is connected to hardware NSS
    HAL_SPI_Transmit(&hspi1, &SPI1_Buffer_Tx[k], 1, 100);
    HAL_SPI_Receive(&hspi4, &SPI4_Buffer_Rx[k], 1, 100);
    HAL_GPIO_WritePin(GPIOE, GPIO_PIN_9, GPIO_PIN_SET);
    k++;
  }
  k = 0;
 
  while (k < 32)
  {
    HAL_UART_Transmit(&huart4, &SPI1_Buffer_Tx[k], 1, 100);
    k++;
  }
  k = 0;
 
  while (k < 32)
  {
    HAL_UART_Transmit(&huart4, &SPI4_Buffer_Rx[k], 1, 100);
    k++;
  }

In this case the UART shows me such answer

abcdefghijklmnopqrstuvwxyzABCDEF //what was originally in the transmit buffer
 bcdefghijklmnopqrstuvwxyzABCDEF //what was received in the receive buffer

Maybe this was possible because I could read on the slave's side, with such code

HAL_SPI_Receive(&hspi4, &SPI4_Buffer_Rx[k], 1, 100);

Now back to the original project.

At first I assumed that the data transmitted from the master should circulate in the slave somehow and transmit back to the master, so that if I read from the master I should get the original data, but in backwards.

so this was the code.

  while (k < 32)
  {
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_RESET);
    HAL_SPI_Transmit(&hspi1, &SPI1_Buffer_Tx[k], 1, 100);
    HAL_SPI_Receive(&hspi1, &SPI1_Buffer_Rx[k], 1, 100);
    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_14, GPIO_PIN_SET);
    k++;
  }

and what I received from the master is 32 0xFFs. I'm not sure where I'm wrong about.

  1. Does the data actually circulate in the slave's side and is it just me doing something wrong?
  2. The data seems to be correctly transmitted, but the slave hasn't been ordered to transmit anything back to the master. That's why I can't receive meaningful data from the master.

2-1. If so, how do I know that the slave has received the data correctly?

2-2. How do I order the slave to transmit back to the master some meaningful data? I can only debug my code on the master's board.

1 ACCEPTED SOLUTION

Accepted Solutions

Slaves are rarely a "passthrough shift register" (i.e. they are not as simple as a 74HC595), the Rx shift register is usually entirely separate from Tx shift register.

Read datasheet of your slave. Usually, complex SPI-connected devices do have an "identification" or "who-am-I" register, which returns a fixed value, thus allowing some basic functionality testing.

Use an oscilloscope/LA to observe waveforms on the signals, and compare them to those given in the connected device's datasheet.

JW

View solution in original post

7 REPLIES 7
Pavel A.
Evangelist III

Connect MISO with MOSI and do a loopback test

I should've clarify the question correctly. What I want to know is if the slave part is correctly working.

As far as I know, the loopback test tells me if the master part is fine, so I don't think that's the case for me. Thanks though!

Slaves are rarely a "passthrough shift register" (i.e. they are not as simple as a 74HC595), the Rx shift register is usually entirely separate from Tx shift register.

Read datasheet of your slave. Usually, complex SPI-connected devices do have an "identification" or "who-am-I" register, which returns a fixed value, thus allowing some basic functionality testing.

Use an oscilloscope/LA to observe waveforms on the signals, and compare them to those given in the connected device's datasheet.

JW

JunseokOh
Associate II

Thanks for your kind answers!

It took a whole month for me to get this work done, and I'm sure there'll be guys like me in the future, so..

As in the LAN9252 Datasheet page 302/329 and 303/329, you can send "0x0050" to receive "0x92520001", and "0x0064" to receive "0x87654321".

the way you send the data is kinda delicate, and that was the part I kept failing. I was (and am) not fully understanding the principles of SPI communication and you're gonna need an oscilloscope with multiple probes(It took me only 2 days after using the oscilloscope, because before then I couldn't check what I was doing)

Hi @JunseokOh , I worked on the same project. Please send me the code to transmit this address 0x0050 to receive 0x9252.

🙏🙏

dmschap
Associate II

Hey @JunseokOh and @Abdelkodouss please could you post your code for reading the byte order register? When I write 0x0064 I get 0xFF bytes back like in the @JunseokOh's original post (in my case the MISO line from the LAN9252 is dead on the scope - 0xFF corresponds to 0V). Thanks for your time!

For any future sufferers of the same fate, I managed to figure things out. To answer the original question, the below code is working for me to receive 0x87654321 (likely very similar to what you already have). The key thing I had wrong was that I didn't know you have to first:
1. Program the device's EEPROM with an ESI file (use the Beckhoff EEPROM programmer and an ethernet cable)
2. Restart the device

 

#define LAN9252_BYTE_ORDER_REG          0x64
   
uint8_t data1[1];
uint8_t data2[2];
uint8_t result[4];

data1[0] = 0x03;  //0x03
data2[0] = ((LAN9252_BYTE_ORDER_REG >>  & 0xFF);
data2[1] = (LAN9252_BYTE_ORDER_REG & 0xFF);

// Select device
HAL_GPIO_WritePin(EtherCAT_NSS_GPIO_Port, EtherCAT_NSS_Pin, RESET);

// Send and read data
HAL_SPI_Transmit(&hspi3, &data1, 1, 5000);
HAL_SPI_Transmit(&hspi3, &data2, 2, 5000);
HAL_SPI_Receive(&hspi3, &result, 4, 5000);

// Un-select device
HAL_GPIO_WritePin(EtherCAT_NSS_GPIO_Port, EtherCAT_NSS_Pin, SET);

// Compile number
uint32_t byte_test = ((result[3] << 24) | (result[2] << 16) | (result[1] <<  | result[0]);