MATLAB: SPI does not activate Raspberry Pi when run from Simulink while attempting to send more than 4 bytes in a message

raspberry pisimulinkspiwiringpi

I have implemented an s-function block with the s-function builder in Simulink that uses WiringPi to use SPI on the Raspberry Pi 2 Model B. This works when I load 4 bytes or fewer into the buffer to be sent. However, when I try to send 6 bytes, the SPI pins on the Raspberry Pi do not activate at all.
My s-function block takes bytes to be written as an input vector, and outputs bytes read from the peripheral as a vector. Also, this problem only occurs when the input bytes are written to the SPI buffer. The transmission sends perfectly fine if I write test bytes to the buffer inside the block, ignoring the input. It's also perfectly fine if I send 4 bytes that are provided by the input to the block. The "outputs" section of the code looks like this:
uint8_t spiData[6];
int n;
spiData[0] = write[0];
spiData[1] = write[1];
spiData[2] = write[2];
spiData[3] = write[3];
spiData[4] = write[4];
spiData[5] = write[5];
// If the above block is commented out and this is used instead, the transmission succeeds
// spiData[0] = 0x01;
// spiData[1] = 0x00;
// spiData[2] = 0x02;
// spiData[3] = 0x03;
// spiData[4] = 0x04;
// spiData[5] = 0x05;
spi_test[0] = wiringPiSPIDataRW(0,spiData,6) ;
for (n = 0; n < 6; n++){
read[n] = spiData[n];
}
I know that the Raspberry Pi SPI buffer is much larger than 4 bytes, and I'm unsure why writing the input to the SPI buffer should cause it to fail. This input I'm testing with is just a uint8 vector of length 6. Changing the SPI baud rate and the sample time of the simulink model has no effect. Any insights would be appreciated.

Best Answer

A few things I changed to make this work.
Rewrote the wiringPiSPIDataRW function to look like this:
int wiringPiSPIDataRW (int channel, unsigned char *data, int length)
{
struct spi_ioc_transfer spi[length] ;
int i = 0;
channel &= 1 ;
for (i = 0; i < length; i++){
memset(&spi[i], 0, sizeof (spi[i]));
spi[i].tx_buf = (unsigned long)(data + i) ;
spi[i].rx_buf = (unsigned long)(data + i) ;
spi[i].len = sizeof(*(data + i)) ;
spi[i].delay_usecs = spiDelay ;
spi[i].speed_hz = spiSpeeds [channel] ;
spi[i].bits_per_word = spiBPW ;
}
return ioctl (spiFds [channel], SPI_IOC_MESSAGE(length), &spi) ;
}
Apparently the memset is to null is necessary due to changes in the internal RasPi library. The for loop was added to create a separate transfer for each byte.
The data type for the data buffer in the s-function was changed to unsigned char.
The block sample mode was changed to discrete and set to the sample time of the full system.
Related Question