Linux下SPI测试程序
/*
* 说明:SPI通讯实现
* 方式一: 同时发送与接收实现函数: SPI_Transfer()
* 方式二:发送与接收分开来实现
* SPI_Write() 只发送
* SPI_Read() 只接收
* 两种方式不同之处:方式一,在发的过程中也在接收,第二种方式,收与发单独进行
* Created on: 2013-5-28
* Author: lzy
*/
#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 "Debug.h"
#define SPI_DEBUG 0
static const char *device = "/dev/spidev0.0";
static uint8_t mode = 0; /* SPI通信使用全双工,设置CPOL=0,CPHA=0。 */
static uint8_t bits = 8; /* 8bits读写,MSB first。*/
static uint32_t speed = 12 * 1000 * 1000;/* 设置12M传输速度 */
static uint16_t delay = 0;
static int g_SPI_Fd = 0;
static void pabort(const char *s)
{
perror(s);
abort();
}
/**
* 功 能:同步数据传输
* 入口参数 :
* TxBuf -> 发送数据首地址
* len -> 交换数据的长度
* 出口参数:
* RxBuf -> 接收数据缓冲区
* 返回值:0 成功
* 开发人员:Lzy 2013-5-22
*/
int SPI_Transfer(const uint8_t *TxBuf, uint8_t *RxBuf, int len)
{
int ret;
int fd = g_SPI_Fd;
struct spi_ioc_transfer tr ={
.tx_buf = (unsigned long) TxBuf,
.rx_buf = (unsigned long) RxBuf,
.len =len,
.delay_usecs = delay,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
if (ret < 1)
pr_err("can't send spi message");
else
{
#if SPI_DEBUG
int i;
pr_debug("nsend spi message Succeed");
pr_debug("nSPI Send [Len:%d]: ", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("nt");
printf("0x%02X ", TxBuf[i]);
}
printf("n");
pr_debug("SPI Receive [len:%d]:", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("nt");
printf("0x%02X ", RxBuf[i]);
}
printf("n");
#endif
}
return ret;
}
/**
* 功 能:发送数据
* 入口参数 :
* TxBuf -> 发送数据首地址
*len -> 发送与长度
*返回值:0 成功
* 开发人员:Lzy 2013-5-22
*/
int SPI_Write(uint8_t *TxBuf, int len)
{
int ret;
int fd = g_SPI_Fd;
ret = write(fd, TxBuf, len);
if (ret < 0)
pr_err("SPI Write errorn");
else
{
#if SPI_DEBUG
int i;
pr_debug("nSPI Write [Len:%d]: ", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("nt");
printf("0x%02X ", TxBuf[i]);
}
printf("n");
#endif
}
return ret;
}
/**
* 功 能:接收数据
* 出口参数:
* RxBuf -> 接收数据缓冲区
* rtn -> 接收到的长度
* 返回值:>=0 成功
* 开发人员:Lzy 2013-5-22
*/
int SPI_Read(uint8_t *RxBuf, int len)
{
int ret;
int fd = g_SPI_Fd;
ret = read(fd, RxBuf, len);
if (ret < 0)
pr_err("SPI Read errorn");
else
{
#if SPI_DEBUG
int i;
pr_debug("SPI Read [len:%d]:", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("nt");
printf("0x%02X ", RxBuf[i]);
}
printf("n");
#endif
}
return ret;
}
/**
* 功 能:打开设备 并初始化设备
* 入口参数 :
* 出口参数:
* 返回值:0 表示已打开 0XF1 表示SPI已打开 其它出错
* 开发人员:Lzy 2013-5-22
*/
int SPI_Open(void)
{
int fd;
int ret = 0;
if (g_SPI_Fd != 0) /* 设备已打开 */
return 0xF1;
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
else
pr_debug("SPI - Open Succeed. Start Init SPI...n");
g_SPI_Fd = fd;
/*
* 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");
pr_debug("spi mode: %dn", mode);
pr_debug("bits per word: %dn", bits);
pr_debug("max speed: %d KHz (%d MHz)n", speed / 1000, speed / 1000 / 1000);
return ret;
}
/**
* 功 能:关闭SPI模块
*/
int SPI_Close(void)
{
int fd = g_SPI_Fd;
if (fd == 0) /* SPI是否已经打开*/
return 0;
close(fd);
g_SPI_Fd = 0;
return 0;
}
/**
* 功 能:自发自收测试程序
* 接收到的数据与发送的数据如果不一样 ,则失败
* 说明:
* 在硬件上需要把输入与输出引脚短跑
* 开发人员:Lzy 2013-5-22
*/
int SPI_LookBackTest(void)
{
int ret, i;
const int BufSize = 16;
uint8_t tx[BufSize], rx[BufSize];
bzero(rx, sizeof(rx));
for (i = 0; i < BufSize; i++)
tx[i] = i;
pr_debug("nSPI - LookBack Mode Test...n");
ret = SPI_Transfer(tx, rx, BufSize);
if (ret > 1)
{
ret = memcmp(tx, rx, BufSize);
if (ret != 0)
{
pr_err("LookBack Mode Test errorn");
//pabort("error");
}
else
pr_debug("SPI - LookBack Mode OKn");
}
return ret;
}
Linux下SPI测试程序的更多相关文章
- linux驱动基础系列--Linux下Spi接口Wifi驱动分析
前言 本文纯粹的纸上谈兵,我并未在实际开发过程中遇到需要编写或调试这类驱动的时候,本文仅仅是根据源码分析后的记录!基于内核版本:2.6.35.6 .主要是想对spi接口的wifi驱动框架有一个整体的把 ...
- linux 下SPI通信注意事项(待续)
一.2台Linux设备之间使用SPI通信 1.标准Linux只支持Master 模式.但是可以在驱动中修改为Slave模式: 2.硬件SPI可能支持Slave模式,也可能不支持.这个要提前确认好: 3 ...
- [DM8168]Linux下SPI驱动测试
1.内核自带的SPI相关的驱动文件 项目中有CPU与FPGA进行通信,用到SPI接口: SPI头文件在: linux-kernel/include/linux/spi.h SPI实现在: linux- ...
- linux下串口测试程序
通过简单的参数配置,执行文件+串口号+波特率 #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...
- Linux下SPI读写外部寄存器的操作
SPI写寄存器操作: staticvoid mcp251x_write_reg(struct spi_device *spi, uint8_t reg, uint8_t val) { stru ...
- linux下SPI接口和stm32通讯
struct mcu_data{ struct spi_device* spi; struct input_dev *input; struct keymcu_platform_da ...
- 以Linux下的测试程序说明递归型互斥量和普通互斥量的区别
先贴代码和测试结果 // Mutex.h: 对pthread的互斥量的RAII包装 #ifndef _MUTEX_H_ #define _MUTEX_H_ #include <stdio.h&g ...
- 在Linux下的中断方式读取按键驱动程序
// 在Linux下的中断方式读取按键驱动程序 //包含外部中断 休眠 加入poll机制 // 采用异步通知的方式 // 驱动程序发 ---> app接收 (通过kill_fasync()发送) ...
- linux下对2个连通的串口读写遇到的问题
想要分析下zmodem协议,搜索发现linux下的工具lrzsz是一个包含x,y,z modem传输的工具,下载其源码,下载.它可以借助各种串行的接口进行数据传输,比如串口,socket也可以,这点描 ...
随机推荐
- 【转载】java连接MYSQL
原文出自 http://qq163230530.blog.163.com/blog/static/4289250620081186262719/ 这篇文章主要以MySQL为例讲下Java如何连接到数据 ...
- 第一百七十七节,jQuery,知问前端--概述及 jQuery UI
jQuery,知问前端--概述及 jQuery UI 学习要点: 1.项目介绍 2.jQuery UI 3.UI 主题 一.项目介绍 我们重点仿照“知乎”的架构模式来搭建界面和布局,以及大部分前端功能 ...
- python 面向对象类成员(字段 方法 属性)
一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province: # 静态字段 countr ...
- day13迭代器与生成器
三个作业: # 1.编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码 login_dic = {'alex':False} def ...
- jQuery EasyUI介绍
官方定义:http://www.jeasyui.com/ what is JQuery EasyUI ? jQuery EasyUI framework helps you build your we ...
- Axis-Parallel Rectangle
D - Axis-Parallel Rectangle Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Stat ...
- Oracle备份一张表
数据库:myOnly 创建表:myTable 的备份表 myTable_tmpe create table myTable_tmpe as select * from myTable ; 补充: -- ...
- MVC5学习系列
前言 嗷~小弟我又出现了~咳咳..嚎过头了, 先说一说为什么写这个吧,~首先肯定是我自己需要学(废话 - -,)//,之前也写过MVC4的项目,嗯..但是仅限于使用并没有很深入的每个模块去了解, 这段 ...
- dfs_部分和问题
给定整数a1,a2,....,an ,选若干数时它们的和为k. 解析:每个数有两种状态:加.不加. 全部n个数都决定其状态后进行判断.复杂度O(2n) 生成可行解空间多用dfs实现. import j ...
- if you have content fetched asynchronously on pages where SEO is important, SSR might be necessary
if you have content fetched asynchronously on pages where SEO is important, SSR might be necessary