User Space:
#define device "/dev/spidev3.0"
int main(int argc, char * argv [ ])
{
int fd = 0;
int i = 0;
int ret = 0;
bool cs_change_flag = 0;
char spi_path[64] = {0};
char cs_change_buf[2] = {0};
uint8_t writebuf[1024] = {'1','2','3'};
uint8_t readbuf[1024] = {0};
spi_config spi_dcb;
printf("spi test\n");
setbuf(stdout, NULL);
fd = spi_open(device);
if(fd < 0)
{
printf("open spi fail\n");
}
memset(&spi_dcb, 0x0, sizeof(spi_dcb));
spi_dcb.mode = E_S_MODE0;
spi_dcb.bits = E_S_BITS_8;
spi_dcb.speed = E_S_19_2M;
spi_config(fd, &spi_dcb);
/* double work mode */
ret = spi_write_read(fd, writebuf, readbuf, 1024);
printf("\n");
spi_close(fd);
}
int32_t spi_open(int8_t* device)
{
int32_t fd = -1;
if (device!= NULL)
{
fd = open(device, O_RDWR);
if (fd < 0)
{
printf("open spi device error\n");
return -1;
}
}
return fd;
}
typedef struct
{
int mode;
int speed;
int bits;
}spi_config;
int32_t spi_config(int32_t fd, spi_config* spi_dcb)
{
int ret;
if(NULL == spi_dcb)
return -1;
ret = ioctl(fd, SPI_IOC_WR_MODE, &spi_dcb->mode);
if (ret == -1)
{
printf("config spi write mode error \n");
return ret;
}
ret = ioctl(fd, SPI_IOC_RD_MODE, &spi_dcb->mode);
if (ret == -1)
{
printf("config spi read mode error \n");
return ret;
}
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &spi_dcb->bits);
if (ret == -1)
{
printf("config spi transfer bits error \n");
return ret;
}
}
int32_t spi_read(int32_t fd, uint8_t *buf, uint32_t len)
{
int32_t ret;
struct spi_ioc_transfer spi_data;
memset(&spi_data, 0, sizeof(spi_data));
spi_data.rx_buf = (unsigned long)buf;
spi_data.tx_buf = (unsigned long)NULL;
spi_data.len = len;
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &spi_data);
if (ret < 1)
{
printf("spi read error\n");
}
return ret;
}
int32_t spi_write(int32_t fd, uint8_t *buf, uint32_t len)
{
int ret;
struct spi_ioc_transfer spi_data;
memset(&spi_data, 0, sizeof(spi_data));
spi_data.tx_buf = (unsigned long)buf;
spi_data.rx_buf = (unsigned long)NULL;
spi_data.len = len;
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &spi_data);
if (ret < 1)
{
printf("spi write error\n");
}
return ret;
}
int32_t spi_write_read(int32_t fd, uint8_t *write_buf, uint8_t *read_buf, uint32_t len)
{
int ret;
struct spi_ioc_transfer spi_data;
memset(&spi_data, 0, sizeof(spi_data));
spi_data.tx_buf = (unsigned long)write_buf;
spi_data.rx_buf = (unsigned long)read_buf;
spi_data.len = len;
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &spi_data);
if (ret < 1)
{
printf("error write and read\n");
}
return ret;
}
int32_t spi_close(int32_t fd)
{
int32_t ret = 0;
if(fd < 0)
{
printf("fd is invalid\n");
}
ret = close(fd);
return ret;
}
Kernel Space:
kernel dtsi:
spi3: spi3@11013000 {
compatible = "platform,xxx-spi";
platform,pad-select = <0>;
reg = <0 0x11013000 0 0x100>;
interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&topckgen_clk CLK_TOP_UNIVPLL_D6_D2>,
<&topckgen_clk CLK_TOP_SPI_SEL>,
<&infracfg_ao_clk CLK_IFRAO_SPI3>;
clock-names = "parent-clk", "sel-clk", "spi-clk";
};
kernel defconfig:
CONFIG_SPI_PLATFORM_QUADSPI=y
CONFIG_SPI=y
CONFIG_SPI_PLATFORMXXXX=y
CONFIG_SPI_SLAVE_PLATFORM=y
CONFIG_SPI_SPIDEV=y
CONFIG_SPI_SLAVE=y
Driver:
drivers/spi/spi-***(platform).c
drivers/spi/spidev.c
file operation in driver:
static const struct file_operations spidev_fops = {
.owner = THIS_MODULE,
.write = spidev_write,
.read = spidev_read,
.unlocked_ioctl = spidev_ioctl,
.compat_ioctl = spidev_compat_ioctl,
.open = spidev_open,
.release = spidev_release,
.llseek = no_llseek,
};
spidev_write-->spidev_sync_write->spi_sync-->__spi_pump_messages
spidev_read-->spidev_sync_read
详细代码分析后续进行中。。。