编写SPI DAC驱动程序
生活随笔
收集整理的這篇文章主要介紹了
编写SPI DAC驱动程序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
參考資料:用戶態調用spidev操作DAC模塊
一、修改設備樹
&spi0 {dac:dac@00{ compatible = "100ask,dac"; reg = <0>;spi-max-frequency = <10000000>;status="okay";}; };二、編寫驅動程序
#include <linux/init.h> #include <linux/module.h> #include <linux/spi/spi.h> #include <asm/uaccess.h> #include <linux/device.h> #include <linux/of.h>static struct spi_device *dac; static int major;static long spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {int val;int err;int old_val = 0;unsigned char tx_buf[2];unsigned char rx_buf[2];struct spi_message msg;struct spi_transfer xfer[1];int status;memset(&xfer[0], 0, sizeof(xfer));err = copy_from_user(&val, (const void __user *)arg, sizeof(int));printk(KERN_ERR"copy from user %d \n", val);val <<= 2;val &= 0xFFC; //只發送8位tx_buf[0] = (val>>8) & 0xff; //低位在前tx_buf[1] = val & 0xff;xfer[0].tx_buf = tx_buf;xfer[0].rx_buf = rx_buf;xfer[0].len = 2;spi_message_init(&msg);spi_message_add_tail(&xfer[0], &msg);status = spi_sync(dac, &msg);printk(KERN_ERR"spi_sync %d \n", status);old_val = (rx_buf[0]<<8) | (rx_buf[1]); //把讀到的數據返回給應用層old_val >>= 2;err = copy_to_user((void __user*)arg, &old_val, sizeof(int));return 0; }static const struct file_operations spidev_fops = {.owner = THIS_MODULE,.unlocked_ioctl = spidev_ioctl, };static struct class *spidev_class;static const struct of_device_id spidev_dt_ids[] = {{ .compatible = "100ask,dac" },{}, };static int spidev_probe(struct spi_device *spi) {dac = spi;major = register_chrdev(0, "100ask_dac", &spidev_fops);spidev_class = class_create(THIS_MODULE, "100ask_dac");device_create(spidev_class, NULL, MKDEV(major, 0), NULL, "100ask_dac");return 0; }static int spidev_remove(struct spi_device *spi) {device_destroy(spidev_class, MKDEV(major, 0));class_destroy(spidev_class);unregister_chrdev(major, "100ask_dac");return 0; }static struct spi_driver spidev_spi_driver = {.driver = {.name = "100ask_spi_dac_drv",.of_match_table = of_match_ptr(spidev_dt_ids),},.probe = spidev_probe,.remove = spidev_remove, };static int __init spidev_init(void) {int status;status = spi_register_driver(&spidev_spi_driver);if(status < 0) {printk(KERN_ERR"spidev_spi_driver error\n");}return status; } module_init(spidev_init);static void __exit spidev_exit(void) {spi_unregister_driver(&spidev_spi_driver); } module_exit(spidev_exit);MODULE_LICENSE("GPL");三、編寫應用程序
#include <stdlib.h> #include <fcntl.h> #include <string.h> #include <stdio.h>#include <sys/ioctl.h> #include <sys/types.h> #include <sys/stat.h>#include <linux/types.h>#define SPI_IOC_WR 123int main(int argc, char **argv) {int fd;unsigned int val;int status;unsigned char tx_buf[2];unsigned char rx_buf[2];if(argc != 3) {printf("Usage: %s /dev/100ask_dac <val>\n", argv[0]);return 0;}fd = open(argv[1], O_RDWR);if(fd < 0) {printf("can not open %s\n", argv[1]);return 1;}val = strtoul(argv[2], NULL, 0);status = ioctl(fd, SPI_IOC_WR, &val);if(status < 0) {printf("SPI_IOC_WR\n");return -1;}printf("Pre val = %d\n", val);return 0; }四、操作過程和結果
[root@firefly-rk3288:/home/picture/spi/dac_drv]# insmod dac_drv.ko [ 456.955496] dac_drv: loading out-of-tree module taints kernel. [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/ 100ask_dac loop2 stderr tty33 tty61 ashmem loop3 stdin tty34 tty62 block/ loop4 stdout tty35 tty63 bus/ loop5 tty tty36 tty7 char/ loop6 tty0 tty37 tty8 console loop7 tty1 tty38 tty9 cpu_dma_latency mali0 tty10 tty39 ttyFIQ0 dht11 mapper/ tty11 tty4 ttyS0 disk/ mem tty12 tty40 ttyS1 dri/ memory_bandwidth tty13 tty41 ttyS2 ds18b20 mmcblk0 tty14 tty42 ttyS3 fb0 mmcblk0p1 tty15 tty43 ttyS4 fd/ mmcblk0p2 tty16 tty44 uhid full mmcblk2 tty17 tty45 uinput fuse mmcblk2boot0 tty18 tty46 urandom hdmi_hdcp1x mmcblk2boot1 tty19 tty47 usbmon0 hevc-service mmcblk2rpmb tty2 tty48 usbmon1 hwrng net/ tty20 tty49 usbmon2 i2c-0 network_latency tty21 tty5 usbmon3 i2c-2 network_throughput tty22 tty50 usbmon4 i2c-3 null tty23 tty51 v4l/ i2c-4 ppp tty24 tty52 vcs i2c-6 ptmx tty25 tty53 vcs1 iio:device0 pts/ tty26 tty54 vcsa input/ ram0 tty27 tty55 vcsa1 irda random tty28 tty56 vendor_storage kmsg rfkill tty29 tty57 vhci log rtc tty3 tty58 video0 loop-control rtc0 tty30 tty59 vpu-service loop0 shm/ tty31 tty6 zero loop1 snd/ tty32 tty60 zram0 [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/100ask_dac 0 [ 472.618281] copy from user 0 [ 472.622078] spi_sync 0 Pre val = 0 [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/100ask_dac 500 [ 475.983460] copy from user 500 [ 475.987103] spi_sync 0 Pre val = 0 [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/100ask_dac 1000 [ 479.009154] copy from user 1000 [ 479.013211] spi_sync 0 Pre val = 500 [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/100ask_dac 200 [ 482.198009] copy from user 200 [ 482.201851] spi_sync 0 Pre val = 1000 [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/100ask_dac 300 [ 484.559005] copy from user 300 [ 484.562844] spi_sync 0 Pre val = 200 [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/100ask_dac 400 [ 486.566507] copy from user 400 [ 486.570157] spi_sync 0 Pre val = 300 [root@firefly-rk3288:/home/picture/spi/dac_drv]# ./dac_test /dev/100ask_dac 500 [ 489.214435] copy from user 500 [ 489.218095] spi_sync 0 Pre val = 400 [root@firefly-rk3288:/home/picture/spi/dac_drv]#總結
以上是生活随笔為你收集整理的编写SPI DAC驱动程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微型计算机三包_买卖合同与“三包”规定
- 下一篇: [摘录]谁说大象不能跳舞目录