zynq7020開發(fā)記錄(持續(xù)更新)--SPI編譯、配置和使用
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[*]]
// 對于 system-top.dts,添加 對spi1節(jié)點的引用聲明 aliases { ethernet0 = &gem0; serial0 = &uart1; serial1 = &uart0; spi0 = &qspi; spi1 = &spi0; }; // 對于 pcw.dtsi,添加對于 spi1 設(shè)備的描述 &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.修改內(nèi)核配置
make ARCH=arm CROSS_COMPILE=/usr/local/gcc-linaro-7.5.0-2019.12-x86_64_ arm-linux-gnueabihf/bin/arm-linux-gnueabihf- menuconfig #### 執(zhí)行修改操作 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
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: // 默認(rèn)為/dev下的設(shè)備節(jié)點,可根據(jù)實際變化,模式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
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點,如有侵權(quán)請聯(lián)系工作人員刪除。