博客專欄

        EEPW首頁 > 博客 > imx6dl spi驅動加載

        imx6dl spi驅動加載

        發布人:電子禪石 時間:2019-05-08 來源:工程師 發布文章

        本項目中主要使用的芯片是imx6dl,內核版本為:

        默認情況下該版本是沒有添加spi驅動的。

        因此,本文目的主要是添加spi的驅動,以及驗證spi的可行性。

        1、驅動配置

        設備樹的修改:

        &ecspi2 {
            fsl,spi-num-chipselects = <1>;
            cs-gpios = <&gpio5 29 0>;
            pinctrl-names = "default";
            pinctrl-0 = <&pinctrl_ecspi2>;
            status = "okay";

            spidev@0 {
               reg = <0>;      /* CS0 */
              compatible = "spidev";
               spi-max-frequency = <40000000>;
           };
        };

        2、內核配置

         輸入make menuconfig,選擇

        device Drivers

             --->SPI supoort

                ---->User mode SPI device driver support

        這樣再編譯源碼,就可以添加spi驅動成功了。下載到imx6后啟動板子,進入/dev目錄下發現多了spidev1.0就成功了。

        3. 驅動測試

        將spi的收發管腳短接在一起,形成閉環,這樣如果發送的數據和接收的數據一致就說明spi測試成功。

        測試代碼如下:

            /*
             * SPI testing utility (using spidev driver)
             *
             * Copyright (c) 2007  MontaVista Software, Inc.
             * Copyright (c) 2007  Anton Vorontsov <avorontsov@ru.mvista.com>
             *
             * This program is free software; you can redistribute it and/or modify
             * it under the terms of the GNU General Public License as published by
             * the Free Software Foundation; either version 2 of the License.
             *
             * Cross-compile with cross-gcc -I/path/to/cross-kernel/include
             */
             
            #include <stdint.h>
            #include <unistd.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <getopt.h>
            #include <fcntl.h>
            #include <sys/ioctl.h>
            #include <linux/types.h>
            #include <linux/spi/spidev.h>
             
            #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
             
            static void pabort(const char *s)
            {
                perror(s);
                abort();
            }
             
            static const char *device = "/dev/spidev1.0";
            static uint8_t mode;
            static uint8_t bits = 8;
            static uint32_t speed = 500000;
            static uint16_t delay;
             
            static void transfer(int fd)
            {
                int ret;
                uint8_t tx[] = {
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                    0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                    0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
                    0xF0, 0x0D,
                };
                uint8_t rx[ARRAY_SIZE(tx)] = {0, };
                struct spi_ioc_transfer tr = {
                    .tx_buf = (unsigned long)tx,
                    .rx_buf = (unsigned long)rx,
                    .len = ARRAY_SIZE(tx),
                    .delay_usecs = delay,
                    .speed_hz = speed,
                    .bits_per_word = bits,
                };
             
                ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
                if (ret < 1)
                    pabort("can't send spi message");
             
                for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
                    if (!(ret % 6))
                        puts("");
                    printf("%.2X ", rx[ret]);
                }
                puts("");
            }
             
            static void print_usage(const char *prog)
            {
                printf("Usage: %s [-DsbdlHOLC3]\n", prog);
                puts("  -D --device   device to use (default /dev/spidev1.1)\n"
                     "  -s --speed    max speed (Hz)\n"
                     "  -d --delay    delay (usec)\n"
                     "  -b --bpw      bits per word \n"
                     "  -l --loop     loopback\n"
                     "  -H --cpha     clock phase\n"
                     "  -O --cpol     clock polarity\n"
                     "  -L --lsb      least significant bit first\n"
                     "  -C --cs-high  chip select active high\n"
                     "  -3 --3wire    SI/SO signals shared\n");
                exit(1);
            }
             
            static void parse_opts(int argc, char *argv[])
            {
                while (1) {
                    static const struct option lopts[] = {
                        { "device",  1, 0, 'D' },
                        { "speed",   1, 0, 's' },
                        { "delay",   1, 0, 'd' },
                        { "bpw",     1, 0, 'b' },
                        { "loop",    0, 0, 'l' },
                        { "cpha",    0, 0, 'H' },
                        { "cpol",    0, 0, 'O' },
                        { "lsb",     0, 0, 'L' },
                        { "cs-high", 0, 0, 'C' },
                        { "3wire",   0, 0, '3' },
                        { "no-cs",   0, 0, 'N' },
                        { "ready",   0, 0, 'R' },
                        { NULL, 0, 0, 0 },
                    };
                    int c;
             
                    c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
             
                    if (c == -1)
                        break;
             
                    switch (c) {
                    case 'D':
                        device = optarg;
                        break;
                    case 's':
                        speed = atoi(optarg);
                        break;
                    case 'd':
                        delay = atoi(optarg);
                        break;
                    case 'b':
                        bits = atoi(optarg);
                        break;
                    case 'l':
                        mode |= SPI_LOOP;
                        break;
                    case 'H':
                        mode |= SPI_CPHA;
                        break;
                    case 'O':
                        mode |= SPI_CPOL;
                        break;
                    case 'L':
                        mode |= SPI_LSB_FIRST;
                        break;
                    case 'C':
                        mode |= SPI_CS_HIGH;
                        break;
                    case '3':
                        mode |= SPI_3WIRE;
                        break;
                    case 'N':
                        mode |= SPI_NO_CS;
                        break;
                    case 'R':
                        mode |= SPI_READY;
                        break;
                    default:
                        print_usage(argv[0]);
                        break;
                    }
                }
            }
             
            int main(int argc, char *argv[])
            {
                int ret = 0;
                int fd;
             
                //parse_opts(argc, argv);
             
                fd = open(device, O_RDWR);
                if (fd < 0)
                    pabort("can't open device");
             
                /*
                 * spi mode
                 */
                ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
                if (ret == -1)
                    pabort("can't set spi mode");
             
                ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
                if (ret == -1)
                    pabort("can't get spi mode");
             
                /*
                 * bits per word
                 */
                ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
                if (ret == -1)
                    pabort("can't set bits per word");
             
                ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
                if (ret == -1)
                    pabort("can't get bits per word");
             
                /*
                 * max speed hz
                 */
                ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
                if (ret == -1)
                    pabort("can't set max speed hz");
             
                ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
                if (ret == -1)
                    pabort("can't get max speed hz");
             
                printf("spi mode: %d\n", mode);
                printf("bits per word: %d\n", bits);
                printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
             
                transfer(fd);
             
                close(fd);
             
                return ret;
            }

         

        編譯測試代碼,在arm板下運行結果如下,說明spi數據發送成功。

         
        ---------------------
        作者:_華子_
        來源:CSDN
        原文:https://blog.csdn.net/suixiangzhe/article/details/86609009
        版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

        *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



        關鍵詞:

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 新乡市| 仁化县| 黄石市| 白山市| 岱山县| 龙州县| 曲阳县| 马鞍山市| 贡嘎县| 永吉县| 彭泽县| 涿鹿县| 高安市| 江西省| 醴陵市| 三台县| 宽城| 扶余县| 鸡泽县| 昆明市| 贺州市| 延寿县| 东宁县| 探索| 视频| 昭觉县| 山阴县| 那坡县| 阜南县| 霍城县| 焦作市| 扎囊县| 绥中县| 镇平县| 泽库县| 苏尼特左旗| 桑植县| 甘洛县| 南郑县| 保德县| 永年县|