SPI测试

概述

SPI控制器驱动的测试:短接MOSI和MISO,通过操作spidev设备,进行自发自收,如果发送数据和测试数据一样,说明SPI控制器MASTER

代码

/*                                                                                                                                                                                           
 * Copyright 2004-2009 Freescale Semiconductor, Inc. All rights reserved.       
 */                                                                             
                                                                                
/*                                                                              
 * The code contained herein is licensed under the GNU General Public           
 * License. You may obtain a copy of the GNU General Public License             
 * Version 2 or later at the following locations:                               
 *                                                                              
 * http://www.opensource.org/licenses/gpl-license.html                          
 * http://www.gnu.org/copyleft/gpl.html                                         
 */                                                                             
                                                                                
#include <sys/types.h>                                                          
#include <sys/stat.h>                                                           
#include <fcntl.h>                                                              
#include <sys/ioctl.h>                                                          
#include <unistd.h>                                                             
#include <stdio.h>                                                              
#include <stdlib.h>                                                             
#include <string.h>                                                             
#include <errno.h>                                                              
#include <linux/types.h>                                                        
#include <linux/spi/spidev.h>                                                   
                                                                                
#define BUF_MAX_SIZE    0x1000                                                  
#define DEV_SPI1        "/dev/spidev1.0"                                        
#define DEV_SPI2        "/dev/spidev2.4"                                        
#define DEV_SPI3        "/dev/spidev3.4"                                        
static unsigned char mode;                                                      
static unsigned char bits_per_word = 8;                                         
static unsigned int speed = 100000;                                             
                                                                                
char *buffer;                                                                   
                                                                                
void help_info(const char *appname)                                             
{                                                                               
        printf("\n"                                                             
               "*******************************************************\n"      
               "*******    Test Application for SPI driver    *********\n"      
               "*******************************************************\n"      
               "*    This test sends bytes of the last parameter to   *\n"      
               "*    a specific SPI device. The maximum transfer      *\n"      
               "*    bytes are 4096 bytes for bits per word less than *\n"      
               "*    8(including 8), 2048 bytes for bits per word     *\n"      
               "*    between 9 and 16, 1024 bytes for bits per word   *\n"      
               "*    larger than 17(including 17). SPI writes data    *\n"      
               "*    received data from the user into Tx FIFO and     *\n"      
               "*    waits for the data in the Rx FIFO. Once the data *\n"      
               "*    is ready in the Rx FIFO, it is read and sent to  *\n"      
               "*    user. Test is considered successful if data      *\n"      
               "*    received = data sent.                            *\n"      
               "*                                                     *\n"      
               "*    NOTE: As this test is intended to test the SPI   *\n"      
               "*    device,it is always configured in loopback mode  *\n"      
               "*    reasons is that it is dangerous to send ramdom   *\n"      
               "*    data to SPI slave devices.                       *\n"      
               "*                                                     *\n"      
               "*    Options : %s                                      \n"      
               "                  [-D spi_no]  [-s speed]              \n"      
               "                  [-b bits_per_word]                   \n"      
               "                  [-H] [-O] [-C] <value>               \n"      
               "*                                                     *\n"      
               "*    <spi_no> - CSPI Module number in [0, 1, 2]       *\n"      
               "*    <speed> - Max transfer speed                     *\n"      
               "*    <bits_per_word> - bits per word                  *\n"      
               "*    -H - Phase 1 operation of clock                  *\n"      
               "*    -O - Active low polarity of clock                *\n"      
               "*    -C - Active high for chip select                 *\n"      
               "*    <value> - Actual values to be sent               *\n"                                                                                                                   
               "*******************************************************\n"      
               "\n", appname);                                                  
} 
int check_data_integrity(char *buf1, char *buf2, int count)                     
{                                                                               
        int result = 0;                                                         
        int i;                                                                  
        short *tmp1_s = NULL, *tmp2_s = NULL;                                   
        int *tmp1_i = NULL, *tmp2_i = NULL;                                     
        int mask;                                                               
                                                                                
        if (bits_per_word > 16) {                                               
                tmp1_i = (int *)buf1;                                           
                tmp2_i = (int *)buf2;                                           
                count /= 4;                                                     
        } else if (bits_per_word > 8) {                                         
                tmp1_s = (short *)buf1;                                         
                tmp2_s = (short *)buf2;                                         
                count /= 2;                                                     
        }                                                                       
        mask = (1 << bits_per_word) - 1;                                        
                                                                                
        for (i = 0; i < count; i++) {                                           
                if (bits_per_word > 16) {                                       
                        if ((tmp1_i[i] & mask) != tmp2_i[i]) {                  
                                printf("Corrupted data at %d wbuf = %d rbuf = %d\n",
                               i, tmp1_i[i], tmp2_i[i]);                        
                                result = -1;                                    
                        }                                                       
                } else if (bits_per_word > 8) {                                 
                        if ((tmp1_s[i] & (short) mask) != tmp2_s[i]) {          
                                printf("Corrupted data at %d wbuf = %d rbuf = %d\n",
                               i, tmp1_s[i], tmp2_s[i]);                        
                                result = -1;                                    
                        }                                                       
                } else                                                                                                                                                                       
                        if ((buf1[i] & (char) mask) != buf2[i]) {               
                                printf("Corrupted data at %d wbuf = %d rbuf = %d\n",
                               i, buf1[i] & (char) mask, buf2[i]);              
                                result = -1;                                    
                        }                                                       
        }                                                                       
                                                                                
        return result;                                                          
} 
static int transfer(int fd, char *tbuf, char *rbuf, int bytes)                  
{                                                                               
        int ret;                                                                
                                                                                
        struct spi_ioc_transfer tr = {                                          
                .tx_buf = (unsigned long)tbuf,                                  
                .rx_buf = (unsigned long)rbuf,                                  
                .len = bytes,                                                   
        };                                                                      
                                                                                
        ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);                               
        if (ret == 1)                                                           
                printf("can't send spi message");                               
        return ret;                                                             
}   
int execute_buffer_test(int spi_id, int len, char *buffer)                      
{                                                                               
        char *rbuf;                                                             
        int res = 0;                                                            
        int fd = -1;                                                            
                                                                                
        if (spi_id == 0) {                                                      
                fd = open(DEV_SPI1, O_RDWR);                                    
        } else if (spi_id == 1) {                                               
                fd = open(DEV_SPI2, O_RDWR);                                    
        } else if (spi_id == 2) {                                               
                fd = open(DEV_SPI3, O_RDWR);                                    
        }                                                                       
                                                                                
        if (fd < 0) {                                                           
                printf("Error:cannot open device "                              
                       "(Maybe not present in your board?)\n");                 
                return -1;                                                      
        }                                                                       
                                                                                
        res = ioctl(fd, SPI_IOC_WR_MODE, &mode);                                
        if (res == -1) {                                                        
                printf("can't set spi mode");                                   
                goto exit;                                                      
        }                                                                       
                                                                                
        res = ioctl(fd, SPI_IOC_RD_MODE, &mode);                                
        if (res == -1) {                                                        
                printf("can't set spi mode");                                   
                goto exit;                                                      
        }                                                                       
        /*                                                                      
         * bits per word                                                                                                                                                                     
         */                                                                     
        res = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);              
        if (res == -1) {                                                        
                printf("can't set bits per word");                              
                goto exit;                                                      
}                                                                       
                                                                                
        res = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits_per_word);              
        if (res == -1) {                                                        
                printf("can't get bits per word");                              
                goto exit;                                                      
        }                                                                       
                                                                                
        /*                                                                      
         * max speed hz                                                         
         */                                                                     
        res = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);                       
        if (res == -1) {                                                        
                printf("can't set max speed hz");                               
                goto exit;                                                      
        }                                                                       
                                                                                
        res = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);                       
        if (res == -1) {                                                        
                printf("can't get max speed hz");                               
                goto exit;                                                      
        }                                                                       
                                                                                
        printf("spi mode: %d\n", mode);                                         
        printf("bits per word: %d\n", bits_per_word);                           
        printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);               
                                                                                
        rbuf = malloc(len);                                                     
        memset(rbuf, 0, len);                                                   
                                                                                
        res = transfer(fd, buffer, rbuf, len);                                  
        if (res < 0) {                                                                                                                                                                       
                printf("Failed transferring data: %d\n", errno);                
                return -1;                                                      
        }                                                                       
        res = check_data_integrity(buffer, rbuf, len);                          
        printf("Data sent : %s\n", (char *)buffer);                             
        printf("Data received : %s\n", (char *)rbuf);                           
                                                                                
        if (res != 0) {                                                         
                printf("Test FAILED.\n");                                       
        } else {                                                                
                printf("Test PASSED.\n");                                       
        }                                                                       
        free(rbuf);                                                             
exit:                                                                           
        close(fd);                                                              
                                                                                
        return 0;                                                               
}                                                                               
   int main(int argc, char **argv)                                                 
{                                                                               
        int spi_id;                                                             
        int bytes, len;                                                         
        int res;                                                                
        int i;                                                                  
                                                                                
        if (argc <= 1) {                                                        
                help_info(argv[0]);                                             
                return 1;                                                       
        }                                                                       
                                                                                
        mode = 0;                                                               
        for(i = 1; i < argc; i++) {                                             
                if(!strcmp(argv[i], "-D")) {                                    
                        i++;                                                    
                        spi_id = atoi(argv[i]);                                 
                        if (spi_id < 0 || spi_id > 2) {                         
                                printf("invalid parameter for device option\n");
                                help_info(argv[0]);                             
                                return -1;                                      
                        }                                                       
                } else if(!strcmp(argv[i], "-s")) {                             
                        i++;                                                    
                        speed = atoi(argv[i]);                                  
                } else if(!strcmp(argv[i], "-b")) {                             
                        i++;                                                    
                        bits_per_word = atoi(argv[i]);                          
                } else if(!strcmp(argv[i], "-H"))                               
                        mode |= SPI_CPHA;                                       
                else if(!strcmp(argv[i], "-O"))                                 
                        mode |= SPI_CPOL;                                                                                                                                                    
                else if(!strcmp(argv[i], "-C"))                                 
                        mode |= SPI_CS_HIGH;                                    
                else if((i != (argc - 1))) {                    
                
                   printf("invalid parameter\n");                          
                        help_info(argv[0]);                                     
                        return -1;                                              
                }                                                               
        }                                                                       
                                                                                
        bytes = strlen((char *)argv[argc - 1]);                                 
        if (bytes < 1) {                                                        
                printf("invalid parameter for buffer size\n");                  
                help_info(argv[0]);                                             
                return -1;                                                      
        }                                                                       
                                                                                
        /* The spidev driver copies len of bytes to tx buffer, and sends len of 
           units to SPI device. So it will send much more data to the SPI       
           device when bits per word is larger than 8, we only care the         
           first len of bytes for this test */                                  
        len = bytes;                                                            
        if (bits_per_word <= 8 && bytes > BUF_MAX_SIZE)                         
                len = BUF_MAX_SIZE;                                             
        else if (bits_per_word <= 16 && bytes > BUF_MAX_SIZE/2)                 
                len = BUF_MAX_SIZE/2;                                           
        else if (bytes > BUF_MAX_SIZE/4)                                        
                len = BUF_MAX_SIZE/4;     
                                                                               
        buffer = malloc(BUF_MAX_SIZE);                                          
        memset(buffer, 0, BUF_MAX_SIZE);                                        
        strcpy(buffer, (char *)argv[argc-1]);                                   
        printf("Execute data transfer test: %d %d %s\n", spi_id, len, buffer);  
        res = execute_buffer_test(spi_id, len, buffer);                         
        free(buffer);                                                           
        return res;                                                             
}   

使用

./mxc_spi_test1.out -D 1 -s 1000000 -b 8 -H -O -C E6E0E6E00001E6E00000

-D:制定设备,选择1,对应代码的DEV_SPI1,系统对应设备
-s: 设置spi传输最大速率
-b: 设置spi传送和接受数据的位宽
-H: SPI_CPHA 时钟相位
-O: SPI_CPOL 时钟极性
-C: SPI_CS_HIGH 高使能
E6E0E6E00001E6E00000: 发送的数据

会看到

Data Sent:   ****
Data received: ***
Test PASSED.
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 对于Linux下的SPI(串行外设接口)测试工具,可以使用spi_test工具进行测试spi_test工具是一个非常常用的测试工具,它可以对SPI设备进行读写操作,并且支持多种不同的模式和设置。 要进行SPI测试,首先需要安装spi_test工具。可以使用apt-get命令在Linux系统中安装spi_test: sudo apt-get install spi-tools 安装完成后,可以通过spi_test命令来进行SPI测试。以下是一些常用的spi_test命令参数和用法: - -s <speed>: 设置传输速度,如-s 1000000表示设置传输速度为1MHz。 - -D <delay>: 设置传输延迟,如-D 2000表示设置传输延迟为2ms。 - -b <bits per word>: 设置每个字的位数,如-b 8表示使用8个位表示每个字。 - -c <channel>: 设置SPI通道号,如-c 0表示使用SPI0通道。 - -O <order>: 设置数据传输顺序,如-O msb表示设置传输顺序为最高位优先。 - -P: 启用循环模式。 除了这些常用的参数外,spi_test还支持其他一些更高级的功能,如模拟模式、帧传输等。 总的来说,linux spi_test工具是一个功能强大的SPI测试工具,它可以帮助我们对SPI设备进行读写操作,并且灵活可配置。使用spi_test可以方便地测试SPI设备的功能和性能。 ### 回答2: Linux spi 测试工具是用于测试和调试 Linux 操作系统中的 SPI 总线和设备的工具。SPI(Serial Peripheral Interface)是一种串行数据传输协议,用于在微控制器、传感器、外设等之间进行通信。 Linux 操作系统提供了许多用于测试和调试 SPI 总线和设备的工具,以下是一些常用的工具: 1. spidev_test:spidev_test 是 Linux 内核自带的一个简单实用的测试工具,用于测试 SPI 总线上的传输速率、模式和数据传输等功能。可以使用该工具发送和接收 SPI 数据。 2. spi-test:spi-test 是一个开源的命令行工具,用于测试 SPI 总线和设备之间的通信。它可以通过命令行参数设置 SPI 的配置选项,并提供了发送和接收数据的功能。可以用它进行数据传输的测试和调试。 3. spidev_test.c:这是一个示例源代码文件,可以用于编写自己的 SPI 测试工具。它提供了一个基本的用户空间 API,用于与 SPI 设备进行通信。可以根据自己的需求修改和扩展该示例代码,实现更加复杂的 SPI 测试功能。 4. Logic Analyzer:除了软件工具,还可以使用逻辑分析仪来进行 SPI 总线的测试和调试。逻辑分析仪可以捕获和分析 SPI 总线上的信号波形,帮助检测和解决通信问题。 通过使用这些 Linux SPI 测试工具,开发者可以方便地测试和调试 SPI 总线和设备,确保它们的正常工作和互联通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值