Project

General

Profile

SPI Comm - can transmit data from Linux, but not receive ยป spi_test.cc

Jared Kirschner, 03/01/2017 06:07 PM

 
#include <stdint.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <iostream>
#include <chrono>

// ... test framework, etc.

const size_t SPI_BUFFER_SIZE = 4;
uint16_t spi_tx_buffer[SPI_BUFFER_SIZE];
uint16_t spi_rx_buffer[SPI_BUFFER_SIZE];

struct spi_ioc_transfer xfer[1];

int spi_init()
{
int file;
uint8_t mode, lsb, bits;
uint32_t speed;

if ((file = open("/dev/spidev32766.0", O_RDWR)) < 0)
{
printf("Failed to open the bus.");
return -1;
}

// ... mode reading and writing

printf("file: spi mode %d, %d bits %sper word, %d Hz max\n", mode, bits, lsb ? "(lsb first) " : "", speed);

memset(xfer, 0, sizeof(spi_ioc_transfer));

xfer[0].tx_buf = (unsigned long)spi_tx_buffer;
xfer[0].len = 20; // Length of command to write
xfer[0].cs_change = 1; // Do NOT Keep CS activated
xfer[0].delay_usecs = 0;
xfer[0].speed_hz = 100000;
xfer[0].bits_per_word = 16;

return file;
}

uint16_t* spi_read(int file)
{
int status;

memset(spi_tx_buffer, 0, sizeof spi_tx_buffer);
memset(spi_rx_buffer, 0, sizeof spi_rx_buffer);

spi_tx_buffer[0] = 0x8330;

xfer[0].tx_buf = (unsigned long)spi_tx_buffer;
xfer[0].len = 2; // Length of command to write/read
xfer[0].rx_buf = (unsigned long)spi_rx_buffer;

status = ioctl(file, SPI_IOC_MESSAGE(1), xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE");
}

// Allow way more than enough time for transfer to occur
sleep(1);

printf("rx: ");
for (uint16_t i = 0; i < SPI_BUFFER_SIZE; i++)
{
printf("%04X ", spi_rx_buffer[i]);
}
printf("\n");

return spi_rx_buffer;
}


void main()
{
int spidev_fd = spi_init();
if (spidev_fd < 0)
{
printf("Failed to open!");
return;
}

// Timeout after 10 seconds
std::cout << "STARTING SPI" << std::endl;
auto timeout_time = std::chrono::high_resolution_clock::now() + std::chrono::seconds(10);
while (std::chrono::high_resolution_clock::now() < timeout_time)
{
spi_read(spidev_fd); //reading the address 0xE60E
std::cout << "BUFFER: " << spi_rx_buffer << std::endl;

usleep(100000);
}

close(spidev_fd);
}
    (1-1/1)