I found a solution. You can use the Linux spidev. It is the standard SPI interface for Linux microcomputers. With it you can set all the low level SPI settings including the bits per word. Documentation can be found here
https://www.kernel.org/doc/Documentation/spi/spidev.
This is the code I use to enable the spi port:
Code:
/******************************************************************************
*
* Initializes the spi
*
******************************************************************************/
void Lights::initSPI()
{
//SPI setup
int ret = 0;
fd = 0;
fd = open(device, O_RDWR);
if (fd <0)
{
output->printError("can't open device");
}
/*************************************************************************************************
* spi mode
*/
//ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
//if (ret ==-1)
//{
// output->printError("can't set spi mode");
//}
ret = ioctl(fd, SPI_IOC_RD_LSB_FIRST, &msb);
if (ret ==-1)
{
output->printError("can't set spi mode");
}
printf("MSB mode: %d\n",msb);
/*
* bits per word
*/
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
if (ret ==-1)
{
output->printError("can't set bits per word");
}
/*
* max speed hz
*/
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
if (ret ==-1)
{
output->printError("can't set max speed hz");
}
tr.tx_buf = (unsigned long) master_array;
tr.rx_buf = (unsigned long) NULL;
tr.len = total_size *3;
tr.delay_usecs = delay;
tr.speed_hz = speed;
tr.bits_per_word = bits;
printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed /1000);
}
device is a const char* set to one of the following:
Code:
const char *device = "/dev/spidev0.X"; //for the main SPI port with chip select X
const char *device = "/dev/spidev1.0"; //for the SPI port on the Custom Electronics Board
and the rest of the settings in the header are:
Code:
//SPI interface
int fd;
struct spi_ioc_transfer tr;
const char *device = "/dev/spidev0.0";
const uint8_t mode = SPI_MODE_0;
const uint8_t msb = 0;
const uint8_t bits = 8;
const uint32_t speed = 800000;
Then to send/receive data I use the following:
Code:
/**********************************************************************
*
* Sends the frame over SPI
*
**********************************************************************/
void Lights::transmitFrame()
{
finalizeFrame();
if ((ioctl(fd, SPI_IOC_MESSAGE(1), &tr)) ==-1)
{
output->printError("transmit failed");
}
for (uint16_t i = 0; i <segment_cnt; i++)
{
segment_bank[i]->renderFrame();
}
}
I plan on making a class that will do all of the hard work and posting it on Delphi.