
#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 <string>

static const char *device = "/dev/spidev0.0";

static void spi_write(int fd, unsigned char c)
{
	int ret;
	unsigned char rx[1];
	struct spi_ioc_transfer tr;
	tr.tx_buf = (unsigned long)&c;
	tr.rx_buf = (unsigned long)rx;
	tr.len = 1;
	tr.delay_usecs = 0;
	tr.speed_hz = 100000;
	tr.bits_per_word = 8;

	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
	if (ret < 0) throw std::string("can't send data");
}

int main(int argc, char *argv[])
{
	int ret = 0;
	int fd = -1;

	try {

		unsigned char mode = 0;
		unsigned char bits = 8;
		unsigned long speed = 100000;
		uint16_t delay;

		fd = open(device, O_RDWR);
		if (fd == -1) throw std::string("can't open device");

		ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
		if (ret == -1) throw std::string("can't set spi mode");

		ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
		if (ret == -1) throw std::string("can't get spi mode");

		ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
		if (ret == -1) throw std::string("can't set bits per word");

		ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
		if (ret == -1) throw std::string("can't get bits per word");

		ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
		if (ret == -1) throw std::string("can't set max speed hz");

		ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
		if (ret == -1) throw std::string("can't get max speed hz");

		spi_write(fd, 0xd0);
		spi_write(fd, 0xc1);
		spi_write(fd, 0xb2);
		spi_write(fd, 0xa3);
		spi_write(fd, 0x94);
		spi_write(fd, 0x85);
		spi_write(fd, 0x76);
		spi_write(fd, 0x67);
		spi_write(fd, 0x50);
		spi_write(fd, 0x41);
		spi_write(fd, 0x32);
		spi_write(fd, 0x23);
		spi_write(fd, 0x14);
		spi_write(fd, 0x05);

		close(fd);
	} catch (std::string const &e) {
		if (fd >= 0) {
			close(fd);
		}
		puts(e.c_str());
	}

	return ret;
}
