cancel
Showing results for 
Search instead for 
Did you mean: 

SPI HAL library. Transmit 1byte at a time different to all at once.

xrstokes
Associate III

I’m trying to port a project over to freertos on cubeIDE. I require interfaceing with a a W5500 from wizNET but I’m having trouble communicating with the chip. If I send data to the chip in one hit like this it works fine.

   WIZCHIP_CRITICAL_ENTER();

   WIZCHIP.CS._select();

   AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);

   uint8_t addr[4];

      addr[0] = ((AddrSel & 0x00FF0000) >> 16);

      addr[1] = ((AddrSel & 0x0000FF00) >> 8);

      addr[2] = ((AddrSel & 0x000000FF) >> 0);

      addr[3] = wb;

      //wizchip_spi_write_bunch(addr, 4); -->

      uint32_t res = HAL_SPI_Transmit(wiz->spi, addr, 4, wiz->spi_timeout);

      

   WIZCHIP.CS._deselect();

   WIZCHIP_CRITICAL_EXIT();

But if I try and send it in 8 bit chunks like this it doesn’t. I don’t want to rewrite a ton of drivers to fix this. Please help. I’ve looked on the scope and they different outputs.

   WIZCHIP_CRITICAL_ENTER();

   WIZCHIP.CS._select();

   AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_);

   wizchip_spi_write_byte((AddrSel & 0x00FF0000) >> 16);

   wizchip_spi_write_byte((AddrSel & 0x0000FF00) >>  8);

   wizchip_spi_write_byte((AddrSel & 0x000000FF) >> 0);

   wizchip_spi_write_byte(wb);

   //Looks like this

//   void wizchip_spi_write_byte(uint8_t wb)

//   {

//    wiz5500 *wiz = ð

//

//    uint32_t res = HAL_SPI_Transmit(wiz->spi, (uint8_t)wb, 1, wiz->spi_timeout);

//   }

   

   WIZCHIP.CS._deselect();

   WIZCHIP_CRITICAL_EXIT();

Update 1 -> you can’t send a ‘0’ with halspi has this in it

if ((pData == NULL) || (Size == 0U))

 {

   errorcode = HAL_ERROR;

   goto error;

 }

Thanks in advance.

7 REPLIES 7

You could try HAL_SPI_TransmitReceive()

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

Thanks for chiming in so quick there bro. I'm trying to avoid changing any of the massive libraries of got that read and write data on SPI 1 byte at a time.

I've got a callback function that returns for an spi write that is one byte long. But writing to HAL drive 1 byte at a time is failing. If i catch all the bytes and send as a stream it's fine. But I need to get this working for compatibility reasons. For example, in mikroe_c you can do this.

for(int i = 0; i < len; i++)

{

spi_transmit(byte[i]);

}

if i put this on the scope it works but the following doesn't.

for(int i = 0; i < len; i++)

{

HAL_SPI_Transmit(wiz->spi, byte[i], 1, wiz->spi_timeout);

}

byte[i] is a byte, not a pointer. You have to supply the address of it:

HAL_SPI_Transmit(wiz->spi, &(byte[i]), 1, wiz->spi_timeout);

Look at the complier warnings too.

I believe you are probably correct. Despite working on the project for weeks I've come from C#, pointers and integers still busting my balls.

would this work?

void wizchip_spi_write_byte(uint8_t wb)
{
	wiz5500 *wiz = &eth;
 
	uint8_t *pointer = pvPortMalloc(1);
 
	pointer[0] = wb;
 
	uint32_t res = HAL_SPI_Transmit(wiz->spi, pointer, 1, wiz->spi_timeout);
 
	vPortFree(pointer);
}

I wouldn't use dynamic heap memory for that. Potential issues are timing, multi-threading, and heap defragmentation.

You can simply write

void wizchip_spi_write_byte(uint8_t wb)
    {
    	wiz5500 *wiz = &eth;     
    	uint32_t res = HAL_SPI_Transmit(wiz->spi, &wb, 1, wiz->spi_timeout);
    }

The compiler takes care that the address of wb can be taken, i.e. wb will be placed in stack memory.

Thanks so much for the help. I'm not sure what the problem was TBH, but it seems to be working now. Looks like this for anyone else's info.

// brief Callback function to read byte usig SPI.

uint8_t CB_SpiRead(void)

{

uint8_t retrn;

HAL_SPI_Receive(&hspi1, &retrn, 1, 500);

  return retrn;

}

// brief Callback function to write byte usig SPI.

void CB_SpiWrite(uint8_t wb)

{

HAL_SPI_Transmit(&hspi1, &wb, 1, 500);

}

Ayuks.1
Associate II

when debug, everything is good and working. but If I shut down the computer then I cannot connect to the processor again. When you enter the ethernet settings from the control panel and turn the ethernet off and on, it works normally again. how to solve this error. can you help me. my mcu is working tcp server mode. ı am using tcp comunication.

ı am using stm32f407vg .w5500 module .

my code

/* Open socket 0 as TCP_SOCKET with port 5000 /

if((retVal = socket(0, Sn_MR_TCP, 80, SF_TCP_NODELAY)) == 0) {

/ Put socket in LISTEN mode. This means we are creating a TCP server /

if((retVal = listen(0)) == SOCK_OK) {

/ While socket is in LISTEN mode we wait for a remote connection */

while(sockStatus = getSn_SR(0) == SOCK_LISTEN)

delay(600);

/* OK. Got a remote peer. Let's send a message to it */

while(1) {

/* If connection is ESTABLISHED with remote peer */

if(sockStatus = getSn_SR(0) == SOCK_ESTABLISHED) {

/* Retrieving remote peer IP and port number */

getsockopt(0, SO_DESTIP, remoteIP);

getsockopt(0, SO_DESTPORT, (uint8_t*)&remotePort);

sprintf(msg, CONN_ESTABLISHED_MSG, remoteIP[0], remoteIP[1], remoteIP[2], remoteIP[3], remotePort);

PRINT_STR(msg);

while(received_len==0)

{

if((RSR_len = getSn_RX_RSR(0) )> 0)

{

received_len = recv(0, data_buf, RSR_len);

if(data_buf[0] == 1)

{

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15);

sprintf(msg,"adc degeri %d",adc_ntc[0]);

send(0, msg, strlen(msg));

}

else

{

sprintf(msg,"adc degeri %d",adc_ntc[0]);

send(0, msg, strlen(msg));

HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14);

}

}

}

received_len =0;

/* Let's send a welcome message and closing socket */

if(retVal = send(0, GREETING_MSG, strlen(GREETING_MSG)) == (int16_t)strlen(GREETING_MSG))

PRINT_STR(SENT_MESSAGE_MSG);

else { /* Ops: something went wrong during data transfer */

sprintf(msg, WRONG_RETVAL_MSG, retVal);

PRINT_STR(msg);

}

break;

}

else { /* Something went wrong with remote peer, maybe the connection was closed unexpectedly */

sprintf(msg, WRONG_STATUS_MSG, sockStatus);

PRINT_STR(msg);

break;

}

}

} else /* Ops: socket not in LISTEN mode. Something went wrong */

PRINT_STR(LISTEN_ERR_MSG);

} else { /* Can't open the socket. This means something is wrong with W5100 configuration: maybe SPI issue? */

sprintf(msg, WRONG_RETVAL_MSG, retVal);

PRINT_STR(msg);

}

/* We close the socket and start a connection again */

// disconnect(0);

close(0);