Linux SPI从驱动到应用

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

详细代码分析后续进行中。。。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a2591748032-随心所记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值