博客專欄

        EEPW首頁 > 博客 > zynq7020開發記錄(持續更新)--SPI編譯、配置和使用

        zynq7020開發記錄(持續更新)--SPI編譯、配置和使用

        發布人:電子禪石 時間:2024-02-03 來源:工程師 發布文章

        1706960214369416.png

        set_property PACKAGE_PIN G14   [get_ports SPI0_MISO]
        set_property IOSTANDARD LVCMOS33 [get_ports SPI0_MISO]
        
        set_property PACKAGE_PIN J15  [get_ports SPI0_MOSI]
        set_property IOSTANDARD LVCMOS33 [get_ports SPI0_MOSI]
        
        set_property PACKAGE_PIN J18   [get_ports SPI0_SCLK]
        set_property IOSTANDARD LVCMOS33 [get_ports SPI0_SCLK]
        
        set_property PACKAGE_PIN L19   [get_ports SPI_CS_tri_o[0]]
        set_property PACKAGE_PIN M17   [get_ports SPI_CS_tri_o[1]]
        set_property PACKAGE_PIN G19   [get_ports SPI_CS_tri_o[2]]
        # set_property PACKAGE_PIN J20   [get_ports SPI_CS_tri_o[3]]
        # set_property PACKAGE_PIN J19   [get_ports SPI_CS_tri_o[4]]  
        # set_property PACKAGE_PIN F16   [get_ports SPI_CS_tri_o[5]]
        # set_property PACKAGE_PIN F17   [get_ports SPI_CS_tri_o[6]]
        set_property IOSTANDARD LVCMOS33 [get_ports SPI_CS_tri_o[*]]


        image.png

        // 對于 system-top.dts,添加 對spi1節點的引用聲明
        aliases {
        		ethernet0 = &gem0;
        		serial0 = &uart1;
        		serial1 = &uart0;
        		spi0 = &qspi;
        		spi1 = &spi0;
        	};
        
        // 對于 pcw.dtsi,添加對于 spi1 設備的描述
        &spi0 {
        	is-decoded-cs = <0>;
        	num-cs = <3>;
        	status = "okay";
        };
        // 上面pcw.dtsi添加并修改成
        &spi0 {
        	// 下面這三行不變
        	is-decoded-cs = <0>;
        	num-cs = <3>;
        	status = "okay";
        
        	device@0 {
        		compatible = "spidev";
        		reg = <0>;
        		spi-max-frequency = <5000000>;
        		#address-cells = <1>;
        		#size-cells = <1>;
            };
        };

          2.修改內核配置

        make ARCH=arm CROSS_COMPILE=/usr/local/gcc-linaro-7.5.0-2019.12-x86_64_
        arm-linux-gnueabihf/bin/arm-linux-gnueabihf- menuconfig
        #### 執行修改操作
        make ARCH=arm CROSS_COMPILE=/usr/local/gcc-linaro-7.5.0-2019.12-x86_64
        _arm-linux-gnueabihf/bin/arm-linux-gnueabihf- all
        
        ## 配置下面兩個宏使之生效
        CONFIG_SPI_CADENCE = y
        CONFIG_SPI_SPIDEV = y
        # 并打開以下宏
        Device Drivers  --->
        	[*] SPI support  --->
                <*>   Cadence SPI controller
                <*>   Xilinx SPI controllor common module
        		<*>   User mode SPI device driver support

          

        image.png             

        4.測試

        spi_mio.h 
        
        #ifndef _SPI_MIO_H_
        #define _SPI_MIO_H_
        
        #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>
        #include <iostream>
        #include <string>
        #include <cstring>
        #include <fstream>
        #include <sstream>
        #include <queue>
        #include <chrono>
        #include <vector>
        #include <list>
        #include <map>
        #include <numeric> 
        #include <stdexcept>
        #include <utility>
        #include <functional>
        #include <atomic>
        #include <mutex>
        #include <thread> 
        #include <sys/stat.h>           
        #include <sys/types.h>  
        #include <sys/ipc.h>
        #include <sys/msg.h>
        #include <sys/time.h>  
        #include <sys/times.h>        
        #include <unistd.h>                  
        #include <getopt.h>             
        #include <errno.h>  
        #include <sys/mman.h>
        #include <math.h>
        #include <time.h>
        #include <signal.h>
        #include <unistd.h>
        #include <getopt.h>
        #include <sys/ioctl.h>
        #include <linux/types.h>
        #include <linux/fb.h>
        #include <linux/spi/spidev.h>
        #include <termios.h>
        #include <sys/vfs.h>
        #include <mntent.h>
        #include <sys/epoll.h>
        #include <poll.h>
        #include <dirent.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <sys/shm.h>
        
        using namespace std;
        class spi
        {
        private:
            std::string device;
        
            uint32_t mode;
            uint8_t  bits;
            uint32_t speed;
        
        public:
            int fd_spi;
            using ptr = std::shared_ptr<spi>;
        
        public:
            // 默認為/dev下的設備節點,可根據實際變化,模式0,一次傳輸8bits, 速率1e6
            spi(std::string device = "/dev/spidev1.0", uint32_t mode = 0, uint8_t  bits = 8, uint32_t speed = 1e6);
            ~spi();
        
            int init();
            int transfer(int fd, uint8_t *tx, uint8_t *rx, uint32_t len);
            void delay(uint32_t count);   
         
        };
        
        class my_dev : public spi
        {
        private:
            uint8_t my_dev_register_config[3] = {0x01, 0x00, 0x34};
        public:
            using spi::spi;
            my_dev() {}
            ~my_dev() {}
        
            void my_dev_init();
        };
        
        #endif

        spi_mio.cpp
        
        #include "spi_mio.h"
        
        using namespace std;
        
        
        spi::spi(std::string device_, uint32_t mode_, uint8_t  bits_, uint32_t speed_)
        {
            device = device_;
        
            mode = mode_;
            bits = bits_;
            speed = speed_;
        
        	fd_spi = open(device_.c_str(), O_RDWR);
        	if (fd_spi < 0) {
                std::cout << "can't open spi device" << std::endl;
            }
        
            init();
        
        }
        
        spi::~spi()
        {
            if (fd_spi > 0) {
                close(fd_spi);
            }
        }
        
        int spi::init()
        {
            int ret = 0;
            if (fd_spi > 0)
            {
                if (ioctl(fd_spi, SPI_IOC_WR_MODE32, &mode) == -1 ||
                    ioctl(fd_spi, SPI_IOC_RD_MODE32, &mode) == -1 ||
                    ioctl(fd_spi, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1 ||
                    ioctl(fd_spi, SPI_IOC_RD_BITS_PER_WORD, &bits) == -1 ||
                    ioctl(fd_spi, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1 ||
                    ioctl(fd_spi, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1)
                {
                    std::cout << "spi device init failed" << std::endl;
                    return -1;
                }
            }
            return ret;
        }
        
        int spi::transfer(int fd, uint8_t *tx, uint8_t *rx, uint32_t len)
        {
        	int ret = 0;
        
        	struct spi_ioc_transfer tr = {
                                        .tx_buf = (unsigned long)tx,
                                        .rx_buf = (unsigned long)rx,
                                        .len = len, 
                                        // .speed_hz = speed,  
                                        // .bits_per_word = bits,  
                                         };
        
        	ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
        	if (ret < 1){
                std::cout << "can't send spi message" << std::endl;
                return -1;
            }
        	return ret;	
        }
        
        void spi::delay(uint32_t count)
        {
            uint32_t fool = 0;
            while (count--){
               fool++; 
            }
        }
        
        void my_dev::my_dev_init()
        {
            uint8_t recv[8];
        	write(fd_spi, my_dev_register_config, 3);
            // transfer(fd_spi, my_dev_register_config, recv, 3);	// 用于雙向傳輸
        }
        main.cpp
        
        #include "spi_mio.h"
        
        int main()
        {
            my_dev dev1;
            dev1.my_dev_init();
        	return 0;
        }


        原文鏈接:https://blog.csdn.net/Vanau/article/details/122460021


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



        關鍵詞: zynq

        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 姚安县| 南昌市| 株洲县| 尖扎县| 凤山市| 都兰县| 闸北区| 汝城县| 城固县| 尖扎县| 祁门县| 祁连县| 永寿县| 库伦旗| 九台市| 绥滨县| 东宁县| 北安市| 门头沟区| 吴江市| 新竹县| 延边| 五家渠市| 石河子市| 海淀区| 昌宁县| 榆树市| 宣威市| 萝北县| 湘潭县| 镇沅| 南昌市| 汝城县| 浪卡子县| 萍乡市| 许昌县| 新竹市| 苗栗县| 黎城县| 漠河县| 高阳县|