SPI - Manual control of CS line and sending and receiving 1 byte at a time.

I am struggling with something that should be super easy - but my mediocre programming skills are failing me so I beg for your help!  

I am connecting a W5500 wiznet chip to the NRF52. I am using Segger. The SPI device seems fairly standard. Using the standard Nordic SPI library using an array I can write to the registers and read from registers directly, no problem here. However........... the provided SPI driver library that I need to use requires separate and individual control of the chip select (CS) lines and needs to send or receive 1 byte at a time. This is where I am hitting major road blocks. 

For the purposes of testing, I am not trying to use the W5500 library, I am just trying to set the IP address of the device on the NRF52840 sending 1 byte at a time. Again note that I have no issues doing this if I follow the standard SPI examples and send multiple bytes in an array format (unfortunately, the library is not written like this so I can not do it) .

  • Setting chip select line as not used so I can control it through my code and the SPI Nordic driver does not do this function 

#define SPI_SS_PIN          NRF_DRV_SPI_PIN_NOT_USED

Then I do the following

  • Put chip select low
  • Send 1st byte of data
  • Send second byte of data
  • ....
  • Put chip select high 

#define W5500_CS                22

uint8_t TX_DATA[7] = {0,15,4,10,0,0,80};
nrf_gpio_pin_clear(W5500_CS); //sets CS pin to logic 0 low to initiate SPI transfer
w5500_test_write_reg(TX_DATA[0]);
w5500_test_write_reg(TX_DATA[1]);
w5500_test_write_reg(TX_DATA[2]);
w5500_test_write_reg(TX_DATA[3]);
w5500_test_write_reg(TX_DATA[4]);
w5500_test_write_reg(TX_DATA[5]);
w5500_test_write_reg(TX_DATA[6]);
nrf_gpio_pin_set(W5500_CS); //sets CS pin to logic 1 high to stop SPI transfer

The function used to write the byte is also fairly standard

void w5500_test_write_reg(uint8_t tx_data)
{
NRF_LOG_INFO("Write = %d", tx_data);

//**** TX transmition parameters
uint8_t tx_len = 1; // TX number of bytes

spi_xfer_done = false; //**** Set the transfer flag to false
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, tx_data, tx_len, NULL, 0));
while(spi_xfer_done == false){};
}

I get an error when the firmware tries to write the 2nd byte

<info> app: Write = 0
<info> app: Write = 15
<error> app: Fatal error
<warning> app: System reset

In Arduino this is a beyond simple piece of code.......

digitalWrite (CS, LOW);  
  SPI.beginTransaction(xx);    
  Byte_1 = SPI.transfer(xx);
  Byte_2 = SPI.transfer(xx);
  Byte_3 = SPI.transfer(xx);
  Byte_4 = SPI.transfer(xx);
  SPI.endTransaction();
  digitalWrite (CS, HIGH);  
There is something fundamental I am missing, but I dont know what it is. If anyone has some example code showing how to get this working it would be most appreciated. Thanks! 
Parents Reply Children
Related