cancel
Showing results for 
Search instead for 
Did you mean: 

Problem connecting SPI to

CK.3
Associate III

I am new to STM32. I am porting my code from ATMega128 to STM32 for faster thru put . I have to connect W5500 to STM32F103 on SPI2.

To test my understanding of SPI on STM32 after compiling , a small test code in while loop.

 SPI_Write(S0_CR,CR_CLOSE); //#define S0_CR 0x0001, CR_CLOSE 0x10;

data_read = SPI_Read(S0_CR);

used the below sub functions

void SPI_Write(int addr,char data)

{

SPI_select

HAL_SPI_Transmit(&hspi2, ((addr & 0xFF00) >> 8), 1, 100);

HAL_SPI_Transmit(&hspi2, (addr & 0x00FF),1,100);

HAL_SPI_Transmit(&hspi2, (WRITE_OPCODE_S0),1,100);

HAL_SPI_Transmit(&hspi2, data, 1, 100);

SPI_deselect

}

char SPI_Read(int addr)

{

SPI_select

HAL_SPI_Transmit(&hspi2,((addr & 0xFF00) >> 8),1,100);

HAL_SPI_Transmit(&hspi2,(addr & 0x00FF),1,100);

HAL_SPI_Transmit(&hspi2,(READ_OPCODE_S0),1,100);

HAL_SPI_Receive(&hspi2,spi_rec,1,100);

SPI_deselect

return spi_rec;

}

Expected 0x10 (16) in data_read but got zero. thru UART. Tried diagnosing with

if(Err !=HAL_OK)

SPI_Write works to HAL_OK when first line address is not 0x00;

DSO Shows no SCK pulses when it is 0x00 though CS goes low.

Similarly in SPI_Read; line -- HAL_SPI_Receive(&hspi2,spi_rec,1,100); gives !=HAL_OK on UART

My proceeding further depends on clearing these doubts. Request help please.

1 ACCEPTED SOLUTION

Accepted Solutions
CK.3
Associate III

The problem is solved.

The error was because I did not add a Ampersand & prefixed to uint8_t spi_rec in HAL_SPI_Receive(&hspi2, &spi_rec,1,100)

Now the HAL_OK comes thru till the last stage successfully thru UART.

Thanks a ton

View solution in original post

7 REPLIES 7
TDK
Guru

> HAL_SPI_Transmit(&hspi2, ((addr & 0xFF00) >> 8), 1, 100);

> HAL_SPI_Transmit(&hspi2, (addr & 0x00FF),1,100);

> HAL_SPI_Transmit(&hspi2, (WRITE_OPCODE_S0),1,100);

> HAL_SPI_Transmit(&hspi2, data, 1, 100);

It looks like you're trying to send raw data in the first 3 function calls and a pointer to data in the last call. That's not how this function works. You need to provide a pointer to data. One way to do that is the following:

uint8_t value = (addr & 0xFF00) >> 8;
HAL_SPI_Transmit(&hspi2, &value, 1, 100);
value = addr & 0x00FF;
HAL_SPI_Transmit(&hspi2, &value, 1, 100);
value = WRITE_OPCODE_S0;
HAL_SPI_Transmit(&hspi2, &value, 1, 100);

It's unclear how data and spi_rec are defined.

If you feel a post has answered your question, please click "Accept as Solution".
CK.3
Associate III

Thanks for the response.

data_read and spi_rec have been declared as char.

Tried the method recommended on SPI_Read(S0_SR) but always gives Zero. S0_SR being the Socket Status Register where Zero could mean Socket closed or no value.

Still unable to resolve.

TDK
Guru

The code you posted should give you compiler errors. The second argument needs to be a pointer, not a char.

error: invalid conversion from 'char' to 'uint8_t* {aka unsigned char*}' [-fpermissive]
   HAL_UART_Transmit(nullptr, data, 1, 100);
                                          ^

If you feel a post has answered your question, please click "Accept as Solution".
CK.3
Associate III

No Such compiler error threw up. However on your advice declared : uint8_t *spi_rec ;

To track the fault, changed the two sub-functions with if(err != HAL_OK) and used UART1 to check for any error.

if(err != HAL_OK) on the first line of both functions were avoided since the addr only contains 0x00 were no SCK pulses appear on DSO

void SPI_Write(int addr,char data)

{

char err;

SPI_select //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);

uint8_t value = (addr & 0xFF00) >> 8;

err = HAL_SPI_Transmit(&hspi2, &value, 1, 100);

value = addr & 0x00FF;

err = HAL_SPI_Transmit(&hspi2, &value, 1, 100);

if(err != HAL_OK)

{

 strcpy(tx_buf,"Tx2 ? \r\n");

}

else

{

value = (READ_OPCODE_S0);

err = HAL_SPI_Transmit(&hspi2, &value, 1, 100);

if(err != HAL_OK)

{

strcpy(tx_buf,"Tx3 ? \r\n");

}

else

{

value = data;

err = HAL_SPI_Transmit(&hspi2,&value, 1, 100);

if(err != HAL_OK)

{

   strcpy(tx_buf,"Tx4 ? \r\n");

}

else

sprintf(tx_buf,"Tx All OK data %d \r\n",data);

}

}

SPI_deselect

HAL_UART_Transmit(&huart1,tx_buf,strlen(tx_buf), 100);

}

uint8_t SPI_Read(int addr)

{

uint8_t err;

SPI_select //HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);

uint8_t value = (addr & 0xFF00) >> 8;

err = HAL_SPI_Transmit(&hspi2, &value, 1, 100);

value = addr & 0x00FF;

err = HAL_SPI_Transmit(&hspi2, &value, 1, 100);

if(err != HAL_OK)

{

 strcpy(tx_buf,"Rx2 ? \r\n");

}

else

{

value = (READ_OPCODE_S0);

err = HAL_SPI_Transmit(&hspi2, &value, 1, 100);

if(err != HAL_OK)

{

strcpy(tx_buf,"Rx3 ? \r\n");

}

else

{

err = HAL_SPI_Receive(&hspi2,spi_rec, 1, 100);

if(err != HAL_OK)

{

   strcpy(tx_buf,"Rx4 ? \r\n");

}

else

sprintf(tx_buf,"Rx All OK %d \r\n",spi_rec);

}

}

SPI_deselect

HAL_UART_Transmit(&huart1,tx_buf,strlen(tx_buf), 100);

return spi_rec;

}

The while loop now had:

SPI_Write(S0_CR,CR_LISTEN); // CR_LISTEN

 sockstat = SPI_Read(S0_SR); //#define S0_SR

where

#define S0_CR   0x0001   // Socket 0: Command Register Address in W5500

#define S0_SR   0x0003   // Socket 0: Status Register Address

#define CR_LISTEN    0x02  // Wait connection request in tcp mode(Server mode)

The Br@y Terminal showed:

Tx All OK data 2 

Rx4 ? 

Tx All OK data 2 

Rx4 ? 

Tx All OK data 2 

Rx4 ? 

I changed SPI2 configuration in GPIO settings of PB14 (MISO), though in input mode to Pull up --if anything changed in HAL_SPI_Receive ------Nothing changed.

Rx4 ? ------------------------still.

Just going in circles.

TDK
Guru

Maybe start with figuring out why your compiler is silently converting (char) to (uint8_t *) without errors. Then correct the usages of HAL_SPI_Receive where you're still passing a char.

> I changed SPI2 configuration in GPIO settings of PB14 (MISO), though in input mode to Pull up

Relevant SPI pins should be in AF mode.

If HAL_SPI_Receive isn't returning HAL_OK, what is it returning instead? It should not be a mystery. Figure out the return code and use that to help debug.

If you feel a post has answered your question, please click "Accept as Solution".
CK.3
Associate III

With Regards to your 2nd line, SPI2 set up --- PB14(MISO) always showed up as GPIO mode to Input while MOSI and SCK showed up as AF. Only I had changed to Pull up.

Now reverted back to No pull up or down . Should the MISO also show up as AF ?. ( which I am unable to change to AF)

As per your instructions, error in HAL_SPI_Receive is returning 1 which is HAL_ERROR. My understanding is { HAL_OK = 0x00U, HAL_ERROR = 0x01U, HAL_BUSY = 0x02U, HAL_TIMEOUT = 0x03U }; --- on google search.

Regards to your first Line-- Compiler silently converting  (char) to (uint8_t *) without errors. Since I don't know how to go about it, I just converted Char to uint8_t

Problem not yet solved. Thanks for the quick response.

CK.3
Associate III

The problem is solved.

The error was because I did not add a Ampersand & prefixed to uint8_t spi_rec in HAL_SPI_Receive(&hspi2, &spi_rec,1,100)

Now the HAL_OK comes thru till the last stage successfully thru UART.

Thanks a ton