目前我自己编译了系统上去,通过交叉编译一些程序也可以执行了,我试着写了个点灯的程序,是通过操作sys/class/gpio来完成的。目前我想使用iic以及spi,我发现在sys/class/i2c-dev 中有i2c-0 ,但是我的sys/class/spi-master 中没有任何文件,这是不是代表我没有spi外设可供使用? 刚开始学习linux,面对这些我有点摸不到头脑,希望有人可以帮我解惑
离线
如果是V3s, 那么只有一组SPI, 如果你用了SPI Flash那就不能再用SPI外设了。
如果你用TF卡启动,可以参考这个: 荔枝派Zero V3s开发板驱动 ili9341 摆拍
离线
I2C使用方法可以参考荔枝派zero板载的NS2009 电阻触摸屏
Allwinner全志V3s板子用ns2009驱动电阻触摸屏
离线
就是我现在就想类似于单片机的使用方法,可以写程序去调用函数去操作spi口,然后可以连接自己想连接的外设,这个该怎么实现
如果是V3s, 那么只有一组SPI, 如果你用了SPI Flash那就不能再用SPI外设了。
如果你用TF卡启动,可以参考这个: 荔枝派Zero V3s开发板驱动 ili9341 摆拍
离线
就是我现在就想类似于单片机的使用方法,可以写程序去调用函数去操作spi口,然后可以连接自己想连接的外设,这个该怎么实现
bugfix 说:如果是V3s, 那么只有一组SPI, 如果你用了SPI Flash那就不能再用SPI外设了。
如果你用TF卡启动,可以参考这个: 荔枝派Zero V3s开发板驱动 ili9341 摆拍
1. Configuring your kernel:
CONFIG_SPI_SUN4I=y
CONFIG_SPI_SUN6I=y
CONFIG_SPI=y
CONFIG_SPI_MASTER=y
CONFIG_EXPERIMENTAL=y
CONFIG_SPI_SPIDEV=y
2. 修改dts文件
3. 启动Linux后一个 /dev/spidev0.0 设备
/*
spidevlib.c - A user-space program to comunicate using spidev.
Gustavo Zamboni
*/
#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>
char buf[10];
char buf2[10];
extern int com_serial;
extern int failcount;
struct spi_ioc_transfer xfer[2];
//////////
// Init SPIdev
//////////
int spi_init(char filename[40])
{
int file;
__u8 mode, lsb, bits;
__u32 speed=2500000;
if ((file = open(filename,O_RDWR)) < 0)
{
printf("Failed to open the bus.");
/* ERROR HANDLING; you can check errno to see what went wrong */
com_serial=0;
exit(1);
}
///////////////
// Verifications
///////////////
//possible modes: mode |= SPI_LOOP; mode |= SPI_CPHA; mode |= SPI_CPOL; mode |= SPI_LSB_FIRST; mode |= SPI_CS_HIGH; mode |= SPI_3WIRE; mode |= SPI_NO_CS; mode |= SPI_READY;
//multiple possibilities using |
/*
if (ioctl(file, SPI_IOC_WR_MODE, &mode)<0) {
perror("can't set spi mode");
return;
}
*/
if (ioctl(file, SPI_IOC_RD_MODE, &mode) < 0)
{
perror("SPI rd_mode");
return;
}
if (ioctl(file, SPI_IOC_RD_LSB_FIRST, &lsb) < 0)
{
perror("SPI rd_lsb_fist");
return;
}
//sunxi supports only 8 bits
/*
if (ioctl(file, SPI_IOC_WR_BITS_PER_WORD, (__u8[1]){8})<0)
{
perror("can't set bits per word");
return;
}
*/
if (ioctl(file, SPI_IOC_RD_BITS_PER_WORD, &bits) < 0)
{
perror("SPI bits_per_word");
return;
}
/*
if (ioctl(file, SPI_IOC_WR_MAX_SPEED_HZ, &speed)<0)
{
perror("can't set max speed hz");
return;
}
*/
if (ioctl(file, SPI_IOC_RD_MAX_SPEED_HZ, &speed) < 0)
{
perror("SPI max_speed_hz");
return;
}
printf("%s: spi mode %d, %d bits %sper word, %d Hz max\n",filename, mode, bits, lsb ? "(lsb first) " : "", speed);
//xfer[0].tx_buf = (unsigned long)buf;
xfer[0].len = 3; /* Length of command to write*/
xfer[0].cs_change = 0; /* Keep CS activated */
xfer[0].delay_usecs = 0, //delay in us
xfer[0].speed_hz = 2500000, //speed
xfer[0].bits_per_word = 8, // bites per word 8
//xfer[1].rx_buf = (unsigned long) buf2;
xfer[1].len = 4; /* Length of Data to read */
xfer[1].cs_change = 0; /* Keep CS activated */
xfer[0].delay_usecs = 0;
xfer[0].speed_hz = 2500000;
xfer[0].bits_per_word = 8;
return file;
}
//////////
// Read n bytes from the 2 bytes add1 add2 address
//////////
char * spi_read(int add1,int add2,int nbytes,int file)
{
int status;
memset(buf, 0, sizeof buf);
memset(buf2, 0, sizeof buf2);
buf[0] = 0x01;
buf[1] = add1;
buf[2] = add2;
xfer[0].tx_buf = (unsigned long)buf;
xfer[0].len = 3; /* Length of command to write*/
xfer[1].rx_buf = (unsigned long) buf2;
xfer[1].len = nbytes; /* Length of Data to read */
status = ioctl(file, SPI_IOC_MESSAGE(2), xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE");
return;
}
//printf("env: %02x %02x %02x\n", buf[0], buf[1], buf[2]);
//printf("ret: %02x %02x %02x %02x\n", buf2[0], buf2[1], buf2[2], buf2[3]);
com_serial=1;
failcount=0;
return buf2;
}
//////////
// Write n bytes int the 2 bytes address add1 add2
//////////
void spi_write(int add1,int add2,int nbytes,char value[10],int file)
{
unsigned char buf[32], buf2[32];
int status;
memset(buf, 0, sizeof buf);
memset(buf2, 0, sizeof buf2);
buf[0] = 0x00;
buf[1] = add1;
buf[2] = add2;
if (nbytes>=1) buf[3] = value[0];
if (nbytes>=2) buf[4] = value[1];
if (nbytes>=3) buf[5] = value[2];
if (nbytes>=4) buf[6] = value[3];
xfer[0].tx_buf = (unsigned long)buf;
xfer[0].len = nbytes+3; /* Length of command to write*/
status = ioctl(file, SPI_IOC_MESSAGE(1), xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE");
return;
}
//printf("env: %02x %02x %02x\n", buf[0], buf[1], buf[2]);
//printf("ret: %02x %02x %02x %02x\n", buf2[0], buf2[1], buf2[2], buf2[3]);
com_serial=1;
failcount=0;
}
离线
谢谢晕哥和bugfix
离线
@晕哥晕哥,我按照此文章说的编译了内核,开发板上发现了 /dev/spidev32766.0 这个设备。使用例程直接读写SPI,使用示波器查看波形,看不到任何波形是什么问题?
最近编辑记录 cody (2018-12-12 13:30:54)
离线
@cody
离线
@cody http://www.chip-community.org/index.php/SPI_support
用逻辑分析仪呢?能不能抓到
离线
@cody http://www.chip-community.org/index.php/SPI_support
用逻辑分析仪呢?能不能抓到
谢谢 ! 已经用示波器成功抓到了
离线
lilo 说:@cody http://www.chip-community.org/index.php/SPI_support
用逻辑分析仪呢?能不能抓到
谢谢 ! 已经用示波器成功抓到了
好奇是怎么解决的?
离线