官网的的包里的代码是正常且可以用的,后来又搜索到文中的测试代码,决定更符合应用习惯,于是测试一下,并把详细的测试步骤记录下来...
代码来自网络:
感谢作者的劳动及奉献精神
编译后,在板子上测试,开始效果如下:
<span style="font-family: Arial, Helvetica, sans-serif;">....
setup status = 0</span>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
spidev spi0.0: 12000000 Hz (max)
spi mode: 0
bits per word: 8
max speed: 11083 KHz (11 MHz)
SPI - LookBack Mode Test...
Error:
File:<SpiDev.c> Fun:[SPI_LookBackTest] Line:259
LookBack Mode Test error
[root@FORLINX6410]# ls
有错误提示...
查看代码后,决定将调试信息打印出来
将代码调试状态置 “1”
调整后
运行结果:
SPI - Open Succeed. Start Init SPI...spidev spi0.0: setup mode 0, 8 bits/w, 4750000 Hz max --> 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
setup status = 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
spidev spi0.0: spi mode 00
spidev spi0.0: setup mode 0, 8 bits/w, 4750000 Hz max --> 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
setup status = 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
spidev spi0.0: 8 bits per word
spidev spi0.0: setup mode 0, 8 bits/w, 4750000 Hz max --> 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
setup status = 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
spidev spi0.0: 5000000 Hz (max)
spi mode: 0
bits per word: 8
max speed: 4750 KHz (4 MHz)
SPI - LookBack Mode Test...
send spi message Succeed
SPI Send [Len:16]:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
SPI Receive [len:16]:
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
Error:
File:<SpiDev.c> Fun:[SPI_LookBackTest] Line:259
LookBack Mode Test error
打印结果一看,错误很明显:发送和接受结果不一致,所以报错
开始没整明白,到底咋回事?
正常情况下,贴出来的代码肯定是不会有问题的,因为作者没有必要这么整。
因此,出问题时,首先要肯怀疑自己,肯定是自己的原因导致出了问题...
想了想,貌似也只有打开的设备时有问题...
按照这个思路修改
static const char *device = "/dev/spidev1.0";
果然
修改打开设备字符串后,结果如下:
[root@FORLINX6410]# ./spi
SPI - Open Succeed. Start Init SPI...spidev spi1.0: setup mode 0, 8 bits/w, 496268 Hz max --> 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
setup status = 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
spidev spi1.0: spi mode 00
spidev spi1.0: setup mode 0, 8 bits/w, 496268 Hz max --> 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
setup status = 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
spidev spi1.0: 8 bits per word
spidev spi1.0: setup mode 0, 8 bits/w, 11083333 Hz max --> 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
setup status = 0
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
spidev spi1.0: 12000000 Hz (max)
spi mode: 0
bits per word: 8
max speed: 11083 KHz (11 MHz)
SPI - LookBack Mode Test...
send spi message Succeed
SPI Send [Len:16]:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
SPI Receive [len:16]:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F
SPI - LookBack Mode OK
至此,终于OK了
PS:
SPI驱动的实现或者说修改还没整理,在ubuntu上还,其实也不复杂,具体方法网络上也能搜索的到。
想整理得看得顺溜,还是要花点时间的,因为不是虚拟机上装的ubuntu,截图麻烦... 尽快抽空整理整理也...
本不想把代码贴出来,考虑到原作者代码页面乱码加上下载附件需要注册,于是就把作者的代码贴出来了
/*
* 说明: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("\n\t");
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("\n\t");
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 error\n");
else
{
#if SPI_DEBUG
int i;
pr_debug("\nSPI Write [Len:%d]: ", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("\n\t");
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 error\n");
else
{
#if SPI_DEBUG
int i;
pr_debug("SPI Read [len:%d]:", len);
for (i = 0; i < len; i++)
{
if (i % 8 == 0)
printf("\n\t");
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: %d\n", mode);
pr_debug("bits per word: %d\n", 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 error\n");
// pabort("error");
}
else
pr_debug("SPI - LookBack Mode OK\n");
}
return ret;
}
int main(int argc, char *argv[])
{
int ret = 0;
ret = SPI_Open();
if (ret)
return ret;
SPI_LookBackTest();
// unsigned char buf[10];
// SPI_Write(buf, 10);
// SPI_Read(buf, 10);
SPI_Close();
return 0;
}
/*
* Debug.h
* 摘要:用于打印调试信息
* 为了统一控制打印信息是否输出,而用宏定义的打印函数。同时也可以起到开发版本与发布版本是同一个版本
* Created on: 2013-5-22
* Author: lzy
*/
#ifndef DEBUG_H_
#define DEBUG_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#define DEBUG_SWITCH 1 /* 打开调试信息打印功能 */
#define ERR_DEBUG_SWITCH 1 /* 打印错误信息打印功能 */
/**
* 简单打印调试信息
*/
#if DEBUG_SWITCH
#define pr_debug(fmt,args...) printf(fmt, ##args)
#else
#define pr_debug(fmt,args...) /*do nothing */
#endif
/**
* 错误信息打印
* 自动打印发生错误时代码所在的位置
*/
#if ERR_DEBUG_SWITCH
#define pr_err(fmt,args...) printf("\nError:\nFile:<%s> Fun:[%s] Line:%d\n "fmt, __FILE__, __FUNCTION__, __LINE__, ##args)
#else
#define pr_err(fmt,args...) /*do nothing */
#endif
#endif /* DEBUG_H_ */