全志R40平台的tinav2.1系统下打开SPI2接口
1、(可选修改)
Q:\r40_tinav2.1\spi20_r40_tinav2.1\lichee\brandy\build.sh
build_uboot()
{
if [ "x${PLATFORM}" = "xsun50iw1p1" ] || \
[ "x${PLATFORM}" = "xsun50iw2p1" ] || \
[ "x${PLATFORM}" = "xsun50iw6p1" ] || \
[ "x${PLATFORM}" = "xsun50iw3p1" ] || \
[ "x${PLATFORM}" = "xsun8iw12p1" ] || \
[ "x${PLATFORM}" = "xsun8iw10p1" ] || \
[ "x${PLATFORM}" = "xsun8iw11p1" ]; then
cd u-boot-2014.07/
else
cd u-boot-2011.09/
fi
make distclean
if [ "x$MODE" = "xota_test" ] ; then
export "SUNXI_MODE=ota_test"
fi
make ${PLATFORM}_config
make -j16
#make spl
#make fes
if [ ${PLATFORM} = "sun8iw11p1" ]; then
make distclean
make ${PLATFORM}_nor_config
make -j16
#make spl
#make fes
fi
cd - 1>/dev/null
}
2、
Q:\r40_tinav2.1\spi20_r40_tinav2.1\lichee\linux-3.10\drivers\spi\spidev.c
static struct spi_driver spidev_spi_driver = {
.driver = {
.name = "spidev",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(spidev_dt_ids),
},
.probe = spidev_probe,
.remove = spidev_remove,
/* NOTE: suspend/resume methods are not necessary here.
* We don't do anything except pass the requests to/from
* the underlying controller. The refrigerator handles
* most issues; the controller driver handles the rest.
*/
};
3、验证APP程序:
Q:\r40_tinav2.1\spi20_r40_tinav2.1\package\allwinner\spidev20_test\Makefile
##############################################
# OpenWrt Makefile for helloworld program
#
#
# Most of the variables used here are defined in
# the include directives below. We just need to
# specify a basic description of the package,
# where to build our program, where to find
# the source files, and where to install the
# compiled program on the router.
#
# Be very careful of spacing in this file.
# Indents should be tabs, not spaces, and
# there should be no trailing whitespace in
# lines that are not commented.
#
##############################################
include $(TOPDIR)/rules.mk
# Name and release number of this package
PKG_NAME:=spidev20_test
PKG_VERSION:=0.0.1
PKG_RELEASE:=1
# This specifies the directory where we're going to build the program.
# The root build directory, $(BUILD_DIR), is by default the build_mipsel
# directory in your OpenWrt SDK directory
PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME)
include $(BUILD_DIR)/package.mk
# Specify package information for this program.
# The variables defined here should be self explanatory.
# If you are running Kamikaze, delete the DESCRIPTION
# variable below and uncomment the Kamikaze define
# directive for the description below
define Package/spidev20_test
SECTION:=utils
CATEGORY:=Allwinner
TITLE:=spidev20_test just test the SPI2 interface
DEPENDS:=+libpthread
endef
# Uncomment portion below for Kamikaze and delete DESCRIPTION variable above
define Package/spidev20_test/description
If you can't figure out what this program does, you're probably
brain-dead and need immediate medical attention.
endef
# Specify what needs to be done to prepare for building the package.
# In our case, we need to copy the source files to the build directory.
# This is NOT the default. The default uses the PKG_SOURCE_URL and the
# PKG_SOURCE which is not defined here to download the source from the web.
# In order to just build a simple program that we have just written, it is
# much easier to do it this way.
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
define Build/Configure
endef
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR) \
CC="$(TARGET_CC)" \
CFLAGS="$(TARGET_CFLAGS)" -Wall \
LDFLAGS="$(TARGET_LDFLAGS)" \
LIBS="-lpthread" \
all
endef
# We do not need to define Build/Configure or Build/Compile directives
# The defaults are appropriate for compiling a simple program such as this one
# Specify where and how to install the program. Since we only have one file,
# the helloworld executable, install it by copying it to the /bin directory on
# the router. The $(1) variable represents the root directory on the router running
# OpenWrt. The $(INSTALL_DIR) variable contains a command to prepare the install
# directory if it does not already exist. Likewise $(INSTALL_BIN) contains the
# command to copy the binary file from its current location (in our case the build
# directory) to the install directory.
define Package/spidev20_test/install
$(INSTALL_DIR) $(1)/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/spidev20_test $(1)/bin/
endef
# This line executes the necessary commands to compile our program.
# The above define directives specify all the information needed, but this
# line calls BuildPackage which in turn actually uses this information to
# build a package.
$(eval $(call BuildPackage,spidev20_test))
Q:\r40_tinav2.1\spi20_r40_tinav2.1\package\allwinner\spidev20_test\src\Makefile
TARGET = spidev20_test
INCLUDES += -I. -Icommon/
LIBS += -lpthread -lm -lrt
SRCS = spidev20_test.c
OBJS = $(SRCS:.c=.o)
%.o: %.c
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
$(TARGET): $(OBJS)
$(CC) -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
all:$(TARGET)
clean:
rm -rf $(TARGET) *.o *.a *~
cd common && rm -f *.o *.a *.bak *~ .depend
Q:\r40_tinav2.1\spi20_r40_tinav2.1\package\allwinner\spidev20_test\src\spidev20_test.c
/*
* SPI testing utility (using spidev driver)
*
* Copyright (c) 2007 MontaVista Software, Inc.
* Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* Cross-compile with cross-gcc -I/path/to/cross-kernel/include
*/
#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>
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static void pabort(const char *s)
{
perror(s);
abort();
}
//static const char *device = "/dev/spidev0.0";
//static const char *device = "/dev/spidev0.1";
static const char *device = "/dev/spidev2.0";
static uint8_t mode;
static uint8_t bits = 8;
static uint32_t speed = 500000;
static uint16_t delay;
static void transfer(int fd)
{
int ret;
//uint8_t tx[] = {
// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// 0x40, 0x00, 0x00, 0x00, 0x00, 0x95,
// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
// 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD,
// 0xF0, 0x0D,
//};
// CityBrand WelCome U!
uint8_t tx[] = {
0x43, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6E, 0x64, 0x20,
0x57, 0x65, 0x6C, 0x43, 0x6F, 0x6D, 0x65, 0x20, 0x55, 0x21,
0x43, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6E, 0x64, 0x20,
0x57, 0x65, 0x6C, 0x43, 0x6F, 0x6D, 0x65, 0x20, 0x55, 0x21,
0x43, 0x69, 0x74, 0x79, 0x42, 0x72, 0x61, 0x6E, 0x64, 0x20,
0x57, 0x65, 0x6C, 0x43, 0x6F, 0x6D, 0x65, 0x20, 0x55, 0x21,
};
uint8_t rx[ARRAY_SIZE(tx)] = {0, };
struct spi_ioc_transfer tr = {
.tx_buf = (unsigned long)tx,
.rx_buf = (unsigned long)rx,
.len = ARRAY_SIZE(tx),
.delay_usecs = delay,
.speed_hz = speed,
.bits_per_word = bits,
};
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr;);
if (ret < 1)
pabort("can't send spi message");
for (ret = 0; ret < ARRAY_SIZE(tx); ret++) {
//if (!(ret % 6))
// puts(" ");
//printf("%.2X ", rx[ret]);
if (!(ret % 20)){
puts("\n");
}
printf("%c", rx[ret]);
}
//puts("");
puts("\n");
}
static void print_usage(const char *prog)
{
printf("Usage: %s [-DsbdlHOLC3]\n", prog);
puts(" -D --device device to use (default /dev/spidev1.1)\n"
" -s --speed max speed (Hz)\n"
" -d --delay delay (usec)\n"
" -b --bpw bits per word \n"
" -l --loop loopback\n"
" -H --cpha clock phase\n"
" -O --cpol clock polarity\n"
" -L --lsb least significant bit first\n"
" -C --cs-high chip select active high\n"
" -3 --3wire SI/SO signals shared\n");
exit(1);
}
static void parse_opts(int argc, char *argv[])
{
while (1) {
static const struct option lopts[] = {
{ "device", 1, 0, 'D' },
{ "speed", 1, 0, 's' },
{ "delay", 1, 0, 'd' },
{ "bpw", 1, 0, 'b' },
{ "loop", 0, 0, 'l' },
{ "cpha", 0, 0, 'H' },
{ "cpol", 0, 0, 'O' },
{ "lsb", 0, 0, 'L' },
{ "cs-high", 0, 0, 'C' },
{ "3wire", 0, 0, '3' },
{ "no-cs", 0, 0, 'N' },
{ "ready", 0, 0, 'R' },
{ NULL, 0, 0, 0 },
};
int c;
c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);
if (c == -1)
break;
switch (c) {
case 'D':
device = optarg;
break;
case 's':
speed = atoi(optarg);
break;
case 'd':
delay = atoi(optarg);
break;
case 'b':
bits = atoi(optarg);
break;
case 'l':
mode |= SPI_LOOP;
break;
case 'H':
mode |= SPI_CPHA;
break;
case 'O':
mode |= SPI_CPOL;
break;
case 'L':
mode |= SPI_LSB_FIRST;
break;
case 'C':
mode |= SPI_CS_HIGH;
break;
case '3':
mode |= SPI_3WIRE;
break;
case 'N':
mode |= SPI_NO_CS;
break;
case 'R':
mode |= SPI_READY;
break;
default:
print_usage(argv[0]);
break;
}
}
}
int main(int argc, char *argv[])
{
int ret = 0;
int fd;
parse_opts(argc, argv);
fd = open(device, O_RDWR);
if (fd < 0)
pabort("can't open device");
/*
* 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");
printf("spi mode: %d\n", mode);
printf("bits per word: %d\n", bits);
printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);
transfer(fd);
close(fd);
return ret;
}
4、修改配置文件:
Q:\r40_tinav2.1\spi20_r40_tinav2.1\target\allwinner\azalea-m2ultra\configs\sys_config.fex
[jtag_para]
jtag_enable = 1
jtag_ms = port:PB14<3><default><default><default>
jtag_ck = port:PB15<3><default><default><default>
jtag_do = port:PB16<3><default><default><default>
jtag_di = port:PB17<3><default><default><default>
修改为:
[jtag_para]
jtag_enable = 0
;jtag_ms = port:PB14<3><default><default><default>
;jtag_ck = port:PB15<3><default><default><default>
;jtag_do = port:PB16<3><default><default><default>
;jtag_di = port:PB17<3><default><default><default>
;----------------------------------------------------------------------------------
;SPI controller configuration
;----------------------------------------------------------------------------------
[spi0]
spi0_used = 0
spi0_cs_number = 2
spi0_cs_bitmap = 3
spi0_cs0 = port:PC23<3><1><default><default>
spi0_cs1 = port:PI14<2><1><default><default>
spi0_sclk = port:PC2<3><default><default><default>
spi0_mosi = port:PC0<3><default><default><default>
spi0_miso = port:PC1<3><default><default><default>
[spi1]
spi1_used = 0
spi1_cs_number = 2
spi1_cs_bitmap = 3
spi1_cs0 = port:PA0<3><1><default><default>
spi1_cs1 = port:PA4<3><1><default><default>
spi1_sclk = port:PA1<3><default><default><default>
spi1_mosi = port:PA2<3><default><default><default>
spi1_miso = port:PA3<3><default><default><default>
[spi2]
spi2_used = 0
spi2_cs_number = 2
spi2_cs_bitmap = 3
spi2_cs0 = port:PB14<2><1><default><default>
spi2_cs1 = port:PB13<2><1><default><default>
spi2_sclk = port:PB15<2><default><default><default>
spi2_mosi = port:PB16<2><default><default><default>
spi2_miso = port:PB17<2><default><default><default>
[spi3]
spi3_used = 0
spi3_cs_number = 2
spi3_cs_bitmap = 3
spi3_cs0 = port:PA5<3><1><default><default>
spi3_cs1 = port:PA9<3><1><default><default>
spi3_sclk = port:PA6<3><default><default><default>
spi3_mosi = port:PA7<3><default><default><default>
spi3_miso = port:PA8<3><default><default><default>
;----------------------------------------------------------------------------------
;SPI device configuration
;compatible --- device name
;spi-max-frequency --- work frequency
;reg --- chip select
;optional properties: spi-cpha, spi-cpol, spi-cs-high
;----------------------------------------------------------------------------------
;[spi0/spi_board0]
;compatible =
;spi-max-frequency =
;reg =
;spi-cpha
;spi-cpol
;spi-cs-high
修改为:
;----------------------------------------------------------------------------------
;SPI controller configuration
;----------------------------------------------------------------------------------
;spi0有接SPI器件(和PC引脚和NAND冲突),但是空贴!
[spi0]
spi0_used = 0
spi0_cs_number = 2
spi0_cs_bitmap = 3
spi0_cs0 = port:PC23<3><1><default><default>
spi0_cs1 = port:PI14<2><1><default><default>
spi0_sclk = port:PC2<3><default><default><default>
spi0_mosi = port:PC0<3><default><default><default>
spi0_miso = port:PC1<3><default><default><default>
;和gmac0复用冲突了!
[spi1]
spi1_used = 0
spi1_cs_number = 2
spi1_cs_bitmap = 3
spi1_cs0 = port:PA0<3><1><default><default>
spi1_cs1 = port:PA4<3><1><default><default>
spi1_sclk = port:PA1<3><default><default><default>
spi1_mosi = port:PA2<3><default><default><default>
spi1_miso = port:PA3<3><default><default><default>
;大排针J9引出来了!
[spi2]
spi2_used = 1
spi2_cs_number = 2
spi2_cs_bitmap = 3
spi2_cs0 = port:PB14<2><1><default><default>
spi2_cs1 = port:PB13<2><1><default><default>
spi2_sclk = port:PB15<2><default><default><default>
spi2_mosi = port:PB16<2><default><default><default>
spi2_miso = port:PB17<2><default><default><default>
;和gmac0复用冲突了!
[spi3]
spi3_used = 0
spi3_cs_number = 2
spi3_cs_bitmap = 3
spi3_cs0 = port:PA5<3><1><default><default>
spi3_cs1 = port:PA9<3><1><default><default>
spi3_sclk = port:PA6<3><default><default><default>
spi3_mosi = port:PA7<3><default><default><default>
spi3_miso = port:PA8<3><default><default><default>
;----------------------------------------------------------------------------------
;SPI device configuration
;compatible --- device name
;spi-max-frequency --- work frequency
;reg --- chip select
;optional properties: spi-cpha, spi-cpol, spi-cs-high
;----------------------------------------------------------------------------------
;[spi0/spi_board0]
;compatible =
;spi-max-frequency =
;reg =
;spi-cpha
;spi-cpol
;spi-cs-high
[spi2/spi_board2]
compatible = "spidev"
spi-max-frequency = 50000000
reg = 0
;spi-cpha = 0
;spi-cpol = 0
;spi-cs-high = 0
5、刷机之后:
root@TinaLinux:/#
root@TinaLinux:/# find . -name spi*
./bin/spidev20_test
./dev/spidev2.0
./proc/irq/44/spi2
./rom/bin/spidev20_test
./rom/usr/lib/opkg/info/spidev20_test.control
./rom/usr/lib/opkg/info/spidev20_test.list
./sys/bus/spi
./sys/bus/spi/devices/spi2.0
./sys/bus/spi/drivers/spidev
./sys/bus/spi/drivers/spidev/spi2.0
./sys/bus/platform/devices/spi2
./sys/bus/platform/drivers/spi
./sys/bus/platform/drivers/spi/spi2
./sys/devices/soc/spi2
./sys/devices/soc/spi2/spi_master
./sys/devices/soc/spi2/spi_master/spi2
./sys/devices/soc/spi2/spi_master/spi2/spi2.0
./sys/devices/soc/spi2/spi_master/spi2/spi2.0/spidev
./sys/devices/soc/spi2/spi_master/spi2/spi2.0/spidev/spidev2.0
./sys/class/spi_master
./sys/class/spi_master/spi2
./sys/class/spidev
./sys/class/spidev/spidev2.0
./sys/kernel/debug/clk/hosc/pll_periph0/spi2
./sys/kernel/debug/clk/hosc/spi0
./sys/kernel/debug/clk/hosc/spi1
./sys/kernel/debug/clk/hosc/spi3
./sys/module/spidev
./usr/lib/opkg/info/spidev20_test.control
./usr/lib/opkg/info/spidev20_test.list
root@TinaLinux:/#
root@TinaLinux:/#