首页 > 代码库 > spi 子系统

spi 子系统

 /dev/spidev0.0对应ESAM,   /dev/spidev1.2对应ATT7022E

[cpp] view plain copy
  1. #include <stdint.h>  
  2. #include <unistd.h>  
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <getopt.h>  
  6. #include <fcntl.h>  
  7. #include <sys/ioctl.h>  
  8. #include <linux/types.h>  
  9. #include <linux/spi/spidev.h>  
  10.   
  11. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))  
  12.   
  13. static void pabort(const char *s)  
  14. {  
  15.     perror(s);  
  16.     abort();  
  17. }  
  18. /*   /dev/spidev0.0对应ESAM,   /dev/spidev1.2对应ATT7022E */
  1. static const char *device = "/dev/spidev1.2";  /
  2. static uint8_t mode;  
  3. static uint8_t bits = 8;  
  4. static uint32_t speed = 500000;  
  5. static uint16_t delay;  
  6.   
  7. static void transfer(int fd)  
  8. {  
  9.     int ret;  
  10.     uint8_t tx[] = {    //要发送的数据数组  
  11.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  12.         0x40, 0x00, 0x00, 0x00, 0x00, 0x95,  
  13.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  14.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  15.         0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,  
  16.         0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,  
  17.         0xF0, 0x0D,  
  18.     };  
  19.     uint8_t rx[ARRAY_SIZE(tx)] = {0, }; //接收的数据数据  
  20.     struct spi_ioc_transfer tr = {  //声明并初始化spi_ioc_transfer结构体  
  21.         .tx_buf = (unsigned long)tx,  
  22.         .rx_buf = (unsigned long)rx,  
  23.         .len = ARRAY_SIZE(tx),  
  24.         .delay_usecs = delay,  
  25.         .speed_hz = speed,  
  26.         .bits_per_word = bits,  
  27.     };  
  28.     //SPI_IOC_MESSAGE(1)的1表示spi_ioc_transfer的数量  
  29.     ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);   //ioctl默认操作,传输数据  
  30.     if (ret < 1)  
  31.         pabort("can‘t send spi message");  
  32.   
  33.     for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { //打印接收缓冲区  
  34.         if (!(ret % 6))     //6个数据为一簇打印  
  35.             puts("");  
  36.         printf("%.2X ", rx[ret]);  
  37.     }  
  38.     puts("");  
  39. }  
  40.   
  41. static void print_usage(const char *prog)   //参数错误则打印帮助信息  
  42. {  
  43.     printf("Usage: %s [-DsbdlHOLC3]\n", prog);  
  44.     puts("  -D --device   device to use (default /dev/spidev1.1)\n"  
  45.          "  -s --speed    max speed (Hz)\n"  
  46.          "  -d --delay    delay (usec)\n"  
  47.          "  -b --bpw      bits per word \n"  
  48.          "  -l --loop     loopback\n"  
  49.          "  -H --cpha     clock phase\n"  
  50.          "  -O --cpol     clock polarity\n"  
  51.          "  -L --lsb      least significant bit first\n"  
  52.          "  -C --cs-high  chip select active high\n"  
  53.          "  -3 --3wire    SI/SO signals shared\n");  
  54.     exit(1);  
  55. }  
  56.   
  57. static void parse_opts(int argc, char *argv[])  
  58. {  
  59.     while (1) {  
  60.         static const struct option lopts[] = {  //参数命令表  
  61.             { "device",  1, 0, ‘D‘ },  
  62.             { "speed",   1, 0, ‘s‘ },  
  63.             { "delay",   1, 0, ‘d‘ },  
  64.             { "bpw",     1, 0, ‘b‘ },  
  65.             { "loop",    0, 0, ‘l‘ },  
  66.             { "cpha",    0, 0, ‘H‘ },  
  67.             { "cpol",    0, 0, ‘O‘ },  
  68.             { "lsb",     0, 0, ‘L‘ },  
  69.             { "cs-high", 0, 0, ‘C‘ },  
  70.             { "3wire",   0, 0, ‘3‘ },  
  71.             { "no-cs",   0, 0, ‘N‘ },  
  72.             { "ready",   0, 0, ‘R‘ },  
  73.             { NULL, 0, 0, 0 },  
  74.         };  
  75.         int c;  
  76.   
  77.         c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);  
  78.   
  79.         if (c == -1)  
  80.             break;  
  81.   
  82.         switch (c) {  
  83.         case ‘D‘:   //设备名  
  84.             device = optarg;  
  85.             break;  
  86.         case ‘s‘:   //速率  
  87.             speed = atoi(optarg);  
  88.             break;  
  89.         case ‘d‘:   //延时时间  
  90.             delay = atoi(optarg);  
  91.             break;  
  92.         case ‘b‘:   //每字含多少位  
  93.             bits = atoi(optarg);  
  94.             break;  
  95.         case ‘l‘:   //回送模式  
  96.             mode |= SPI_LOOP;  
  97.             break;  
  98.         case ‘H‘:   //时钟相位  
  99.             mode |= SPI_CPHA;  
  100.             break;  
  101.         case ‘O‘:   //时钟极性  
  102.             mode |= SPI_CPOL;  
  103.             break;  
  104.         case ‘L‘:   //lsb 最低有效位  
  105.             mode |= SPI_LSB_FIRST;  
  106.             break;  
  107.         case ‘C‘:   //片选高电平  
  108.             mode |= SPI_CS_HIGH;  
  109.             break;  
  110.         case ‘3‘:   //3线传输模式  
  111.             mode |= SPI_3WIRE;  
  112.             break;  
  113.         case ‘N‘:   //没片选  
  114.             mode |= SPI_NO_CS;  
  115.             break;  
  116.         case ‘R‘:   //从机拉低电平停止数据传输  
  117.             mode |= SPI_READY;  
  118.             break;  
  119.         default:    //错误的参数  
  120.             print_usage(argv[0]);  
  121.             break;  
  122.         }  
  123.     }  
  124. }  
  125.   
  126. int main(int argc, char *argv[])  
  127. {  
  128.     int ret = 0;  
  129.     int fd;  
  130.   
  131.     parse_opts(argc, argv); //解析传递进来的参数  
  132.   
  133.     fd = open(device, O_RDWR);  //打开设备文件  
  134.     if (fd < 0)  
  135.         pabort("can‘t open device");  
  136.   
  137.     /* 
  138.      * spi mode //设置spi设备模式 
  139.      */  
  140.     ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);    //写模式  
  141.     if (ret == -1)  
  142.         pabort("can‘t set spi mode");  
  143.   
  144.     ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);    //读模式  
  145.     if (ret == -1)  
  146.         pabort("can‘t get spi mode");  
  147.   
  148.     /* 
  149.      * bits per word    //设置每个字含多少位 
  150.      */  
  151.     ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);   //写 每个字含多少位  
  152.     if (ret == -1)  
  153.         pabort("can‘t set bits per word");  
  154.   
  155.     ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);   //读 每个字含多少位  
  156.     if (ret == -1)  
  157.         pabort("can‘t get bits per word");  
  158.   
  159.     /* 
  160.      * max speed hz     //设置速率 
  161.      */  
  162.     ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);   //写速率  
  163.     if (ret == -1)  
  164.         pabort("can‘t set max speed hz");  
  165.   
  166.     ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);   //读速率  
  167.     if (ret == -1)  
  168.         pabort("can‘t get max speed hz");  
  169.     //打印模式,每字多少位和速率信息  
  170.     printf("spi mode: %d\n", mode);  
  171.     printf("bits per word: %d\n", bits);  
  172.     printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);  
  173.   
  174.     transfer(fd);   //传输测试  
  175.   
  176.     close(fd);  //关闭设备  
  177.   
  178.     return ret;  
  179. }  

 

spi 子系统