#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>

#define SPI_DEVICE "/dev/spidev1.0"  // Change as per your SPI bus
//#define SPI_MODE SPI_MODE_0
#define SPI_MODE SPI_3WIRE
#define SPI_BITS_PER_WORD 8

#define SPI_SPEED 1000  // 1 Hz


int spi_transfer(int fd, uint8_t *tx_buf, uint8_t *rx_buf, size_t len) {
    struct spi_ioc_transfer transfer = {
        .tx_buf = (unsigned long)tx_buf,
        .rx_buf = (unsigned long)rx_buf,
        .len = len,
        .speed_hz = SPI_SPEED,
        .bits_per_word = SPI_BITS_PER_WORD,
        .delay_usecs = 0,
    };

    return ioctl(fd, SPI_IOC_MESSAGE(1), &transfer);
}

uint8_t read_SPI_CTL_reg(int fd){
	uint8_t SPI_CTL[2] = {0x80, 0x00};
	uint8_t spi_ctl_res[2] = {0x00, 0x00};
	int err_code = spi_transfer(fd, (uint8_t *)SPI_CTL, spi_ctl_res, 2);
    // printf("error code : %d\r\n",err_code);
	// uint8_t ctrl_reg = spi_ctl_res[1];
	for(int i = 0; i < 2; i++){
		printf("%02x ", spi_ctl_res[i]);
	}
	printf("\r\n");
	return err_code;	
}

uint8_t read_version(int fd, uint8_t *buf){
    uint8_t ver_tx_buf[5] = {0xED, 0x00, 0x00, 0x00, 0x00,};
    int err_code = spi_transfer(fd, (uint8_t *)ver_tx_buf, buf, sizeof(ver_tx_buf));
    // printf("error code : %d\r\n",err_code);
    uint8_t version = buf[1];
    return 0;
}


int main() {
    int fd = open(SPI_DEVICE, O_RDWR);
    if (fd < 0) {
        perror("Failed to open SPI device");
        return EXIT_FAILURE;
    }

    uint8_t mode = SPI_MODE;
    uint8_t bits = SPI_BITS_PER_WORD;
    uint32_t speed = SPI_SPEED;

    ioctl(fd, SPI_IOC_WR_MODE, &mode);
    ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);

    int err_code = read_SPI_CTL_reg(fd);
    printf("err_code : 0x%02X\r\n", err_code);
    
    uint8_t ver_rx_buf[5];
    read_version(fd, (uint8_t *)&ver_rx_buf);
    for(int i = 0; i < 5; i++){
        printf("%02X ", ver_rx_buf[i]);
    }
    printf("\r\n");
    close(fd);
    return 0;
}