树莓派5 spi控制
树莓派5 spi控制
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <string.h>
#define SPI_DEVICE_PATH "/dev/spidev0.0"
uint8_t tx_bf[200];
typedef struct spi_args_struct
{
int fd;
uint8_t tx_buffer[1000];
uint8_t rx_buffer[1000];
struct spi_ioc_transfer transfer;
}spi_args_s;
int api_spi_init(char * dev)
{
int fd = 0;
if ((fd = open(dev, O_RDWR)) < 0)
{
perror("Failed to open SPI device");
return -1;
}
return fd;
}
int api_spi_cfg(struct spi_args_struct *spi_args_obj)
{
/* 配置收发缓存 */
spi_args_obj->transfer.tx_buf = (unsigned long) spi_args_obj->tx_buffer;
spi_args_obj->transfer.rx_buf = (unsigned long) spi_args_obj->rx_buffer;
/* Configure SPI mode and bits per word */
uint8_t mode = SPI_MODE_0;
uint8_t bits = 8;
if (ioctl(spi_args_obj->fd, SPI_IOC_WR_MODE, &mode) < 0)
{
perror("Failed to set SPI mode");
close(spi_args_obj->fd);
return -1;
}
if (ioctl(spi_args_obj->fd, SPI_IOC_WR_BITS_PER_WORD, &bits) < 0)
{
perror("Failed to set SPI bits per word");
close(spi_args_obj->fd);
return -1;
}
}
void api_spi_send(struct spi_args_struct *spi_args_obj, uint8_t *data, uint16_t size)
{
spi_args_obj->transfer.len = size;
memcpy((spi_args_obj->tx_buffer), data, spi_args_obj->transfer.len);
printf("Send %d bytes of data max speed: %d Hz.\n", spi_args_obj->transfer.len, spi_args_obj->transfer.speed_hz);
}
spi_args_s spi_args_obj =
{
.transfer =
{
.len = 10,
.delay_usecs = 0,
.speed_hz = 31200000, // SPI speed in Hz
.bits_per_word = 8,
},
};
#if 0 //测试代码
int main()
{
/* Open the SPI device */
spi_args_obj.fd = api_spi_init(SPI_DEVICE_PATH);
/* Configure SPI mode and bits per word */
api_spi_cfg(&spi_args_obj);
/* Send Data */
for (int i = 0; i < 200; i++)
{
tx_bf[i] = i;
}
while (1)
{
api_spi_send(&spi_args_obj, tx_bf, 10);
printf("\r\n");
if (ioctl(spi_args_obj.fd, SPI_IOC_MESSAGE(1), &(spi_args_obj.transfer) ) < 0)
{
perror("Failed to perform SPI transfer");
close(spi_args_obj.fd);
return -1;
}
sleep(2);
printf("sleep out\n");
}
/* Close the SPI device */
close(spi_args_obj.fd);
return 0;
}
#endif
int spi_set_mode(int fd, int mode)
{
return ioctl(fd, SPI_IOC_WR_MODE, &mode);
}
int spi_read_mode(int fd, int mode)
{
return ioctl(fd, SPI_IOC_RD_MODE, &mode);
}
int spi_set_bit_order(int fd, int bit_order)
{
return ioctl(fd, SPI_IOC_WR_LSB_FIRST, bit_order);
}
int spi_read_bit_order(int fd, int bit_order)
{
return ioctl(fd, SPI_IOC_RD_LSB_FIRST, &bit_order);
}
int spi_set_bits_per_word(int fd, int bits_per_word)
{
return ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);
}
int spi_read_bits_per_word(int fd, int bits_per_word)
{
return ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits_per_word);
}
int spi_set_max_speed(int fd, int max_speed)
{
ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &max_speed);
}
int spi_read_max_speed(int fd, int max_speed)
{
ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &max_speed);
}