GV7601 硬件部分官方手册上有给一些示例,但是不太完整。

这里贴出我们设计的原理图,仅供参考。

网上找到一篇关于GV7601 SPI通信的例子

参看:海思3531 GV7601 SPI通信问题

/*生成ko文件源代码*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <linux/delay.h>
//#include <bsp.h>
#include <asm/io.h>#include <linux/sched.h>
#include <linux/delay.h>   //OK
#include <linux/fs.h>  //OK#include <asm/irq.h>  //OK
//#include <mach/regs-gpio.h>
//#include <mach/hardware.h>  //OK  #include <linux/miscdevice.h>  /**鍐呮牳鐗堟湰2.6.32鍔犱互涓嬪ご鏂囦欢***/
//#include <mach/regs-gpio.h>
#include <linux/mm.h>  //OK
#include <linux/pci.h>  //OK
#include <linux/moduleparam.h>  //OK
#include <linux/slab.h>  //OK
#include <linux/errno.h>  //OK
#include <linux/ioctl.h>  //OK
#include <linux/cdev.h>   //OK
#include <linux/string.h>  //OK
#include <linux/list.h>  //OK#include <asm/atomic.h>
#include <asm/unistd.h>#define PDEBUG
#ifdef PDEBUG #define PLOG(fmt,args...) printk(fmt,##args)
#else #define PLOG(fmt,args...) /*do nothing*/
#endif #define DEVICE_NAME "GV7601"
#define GV7601_MAJOR 230  //device numtypedef struct tem{
unsigned short address;
unsigned short value;
}command;command temp;//寄存器读写定义
#define HW_REG(reg)  *((volatile unsigned long *)(reg))
#define Hi3516_gpio_cfgpin(addr,dir) HW_REG(addr) = dir
#define Hi3516_gpio_setpin(addr,value) HW_REG(addr) = value
#define Hi3516_gpio_getpin(addr) HW_REG(addr)//定义地址偏移
#define CPU_BASE 0x200F0000
#define OFFSET_GPIO2_4 0x00A4  //cs
#define OFFSET_GPIO2_5 0x00A8  //SCLK
#define OFFSET_GPIO2_6 0x00AC  //TDI
#define OFFSET_GPIO2_7 0x00B0  //TDO#define GPIO2_4_SET IO_ADDRESS(0x200F00A4)
#define GPIO2_5_SET IO_ADDRESS(0x200F00A8)
#define GPIO2_6_SET IO_ADDRESS(0x200F00AC)
#define GPIO2_7_SET IO_ADDRESS(0x200F00B0)
#define GPIO1_6_SET IO_ADDRESS(0x200F00D4)#define GPIO2_BASE 0x20170000
#define GPIO1_BASE 0x20160000
#define GPIO_DIR 0x400
#define GPIO_DATA2_4                IO_ADDRESS(0x20170040) //CS   1<<6 IO_ADDRESS(GPIO2_BASE+(1<<4))
#define GPIO_DATA2_5                IO_ADDRESS(0x20170080) //sclk 1<<7
#define GPIO_DATA2_6                IO_ADDRESS(0x20170100) //tdi  1<<8
#define GPIO_DATA2_7                IO_ADDRESS(0x20170200) //tdo  1<<9
#define GPIO_DATA1_6                IO_ADDRESS(0x20160100) //reset 1<<8#define GPIO2_DIR IO_ADDRESS(0x20170400)
#define GPIO1_DIR IO_ADDRESS(0x20160400)#define PIN_SDO 9 //
#define PIN_SDI 8
#define PIN_SCLK 7
#define PIN_CS 6 // #define SPI_CMD 0
#define SPI_DATA 1
#define FUN_GPIO    0 static int spi_setcs_gv7601(int ) ;
static int spi_sethigh(int );
static int spi_setlow(int ) ;
static unsigned int spi_readIO_gv7601(int ) ;
static int spi_init_gv7601(void) ;
void SPI_send_gv7601(unsigned short,unsigned short ) ;
unsigned short spi_read_gv7601(unsigned short ) ;
static ssize_t spi_write_data_gv7601(struct file *, command __user *, size_t , loff_t *);
static ssize_t spi_read_data_gv7601(struct file *, command __user *, size_t , loff_t *);
static void set_value(void) ;
static int gv7601_ioctl(struct inode *,struct file *,unsigned int ,unsigned long );// 换成海思的片选信号,两路,低选中一路,高选中一路
static int spi_setcs_gv7601(int number)
{ switch(number){case 1:Hi3516_gpio_setpin(GPIO_DATA2_4,Hi3516_gpio_getpin(GPIO_DATA2_4)&0xFFEF); //拉低break;case 2:Hi3516_gpio_setpin(GPIO_DATA2_4,Hi3516_gpio_getpin(GPIO_DATA2_4)|0x0010); //拉高break; }return 0;
} // set gpio pin level, high: 1, low: 0
// cs    --6
// sclik --7
// tdi         --8
// tdo         --9
// 管脚拉高
static int spi_sethigh(int pin)
{ Hi3516_gpio_setpin(GPIO2_DIR,Hi3516_gpio_getpin(GPIO2_DIR)|(1<<(pin-2)));Hi3516_gpio_setpin(IO_ADDRESS(GPIO2_BASE+(1<<pin)),Hi3516_gpio_getpin(IO_ADDRESS(GPIO2_BASE+(1<<pin)))|(1<<(pin-2)));return 0;
} //管脚拉低
static int spi_setlow(int pin)
{ Hi3516_gpio_setpin(GPIO2_DIR,Hi3516_gpio_getpin(GPIO2_DIR)|(1<<(pin-2)));Hi3516_gpio_setpin(IO_ADDRESS(GPIO2_BASE+(1<<pin)),Hi3516_gpio_getpin(IO_ADDRESS(GPIO2_BASE+(1<<pin)))&(~(1<<(pin-2))));return 0;
} // cs    --4
// sclik --5
// tdi         --6
// tdo         --7
// 读管脚数据
static unsigned int spi_readIO_gv7601(int pin)
{ int i;Hi3516_gpio_setpin(GPIO2_DIR,Hi3516_gpio_getpin(GPIO2_DIR)&(~(1<<(pin-2))));i=Hi3516_gpio_getpin(IO_ADDRESS(GPIO2_BASE+(1<<pin)));if (i!=0)i=1;return i;
} // select pin used for gpio 配置管脚为GPIO
// 换成海思的管脚配置即可
static int spi_init_gv7601()
{ //配置成GPIO口Hi3516_gpio_setpin(GPIO2_4_SET,Hi3516_gpio_getpin(GPIO2_4_SET)&0xFFFC);//csHi3516_gpio_setpin(GPIO2_5_SET,Hi3516_gpio_getpin(GPIO2_5_SET)&0xFFFC);//sclkHi3516_gpio_setpin(GPIO2_6_SET,Hi3516_gpio_getpin(GPIO2_6_SET)&0xFFFC);//tdiHi3516_gpio_setpin(GPIO2_7_SET,Hi3516_gpio_getpin(GPIO2_7_SET)&0xFFFC);//tdoHi3516_gpio_setpin(GPIO1_6_SET,Hi3516_gpio_getpin(GPIO1_6_SET)&0xFFFC);//reset//配置GPIO输入输出方向Hi3516_gpio_setpin(GPIO2_DIR,Hi3516_gpio_getpin(GPIO2_DIR)|0x0070);//cs sclk tdi outHi3516_gpio_setpin(GPIO2_DIR,Hi3516_gpio_getpin(GPIO2_DIR)&0xFF8F);//td0 inHi3516_gpio_setpin(GPIO1_DIR,Hi3516_gpio_getpin(GPIO2_DIR)|0x0040);//reset out//除clk以外全部置高spi_sethigh(6);spi_setlow(7);spi_sethigh(8);spi_sethigh(9);return 0;
} void SPI_send_gv7601(unsigned short address,unsigned short wdata)
{     unsigned short vsignbit; // 写地址   16位spi_setlow(PIN_CS);ndelay(1000);for(vsignbit=0x8000;vsignbit>0;vsignbit>>=1) {     if(address&vsignbit) spi_sethigh(PIN_SDI);else spi_setlow(PIN_SDI);ndelay(1000);spi_setlow(PIN_SCLK);ndelay(2000); spi_sethigh(PIN_SCLK); ndelay(1000);        } ndelay(1000); spi_setlow(PIN_SCLK);//spi_setlow(PIN_SDI);//spi_setlow(PIN_SDO);udelay(100);//写数据 16位        for(vsignbit=0x8000;vsignbit>0;vsignbit>>=1) {     if(wdata&vsignbit) spi_sethigh(PIN_SDI);else spi_setlow(PIN_SDI);ndelay(1000);spi_setlow(PIN_SCLK);ndelay(2000); spi_sethigh(PIN_SCLK); ndelay(1000);   } //spi_sethigh(PIN_SDI);ndelay(1000); spi_setlow(PIN_SCLK);//spi_setlow(PIN_SCLK);//udelay(300);//spi_setlow(PIN_SDI);ndelay(1000);spi_sethigh(PIN_CS);
}  unsigned short spi_read_gv7601(unsigned short address)
{     unsigned short vsignbit,r_data=0; //写命令字spi_setlow(PIN_CS);ndelay(1000);for(vsignbit=0x8000;vsignbit>0;vsignbit>>=1) {     if(address&vsignbit) spi_sethigh(PIN_SDI);else spi_setlow(PIN_SDI);ndelay(1000);spi_setlow(PIN_SCLK);ndelay(2000); spi_sethigh(PIN_SCLK); ndelay(1000);           } //spi_sethigh(PIN_SDI);ndelay(1000);spi_setlow(PIN_SCLK);//udelay(300);spi_setlow(PIN_SDI);udelay(10);for(vsignbit=0x8000;vsignbit>0;vsignbit>>=1) { spi_setlow(PIN_SCLK);ndelay(1000);if(spi_readIO_gv7601(PIN_SDO)) //读 TDO{     r_data = r_data|vsignbit; } ndelay(1000); spi_sethigh(PIN_SCLK); ndelay(2000);        } spi_setlow(PIN_SCLK);ndelay(1000);spi_sethigh(PIN_CS);return r_data;
} //向寄存器写入数据
static ssize_t spi_write_data_gv7601(struct file *pFile, command __user *pData, size_t count, loff_t *off)
{printk("in the write function\n");//加片选?//ndelay(100);memcpy(&temp,pData,count);unsigned short address, wdata;address = temp.address;unsigned short writecommand = 0x0000;wdata = temp.value;writecommand = writecommand + address;SPI_send_gv7601(writecommand,wdata);//udelay(300);//SPI_send_gv7601(wdata);//spi_setlow(PIN_SCLK);return count;
}static ssize_t spi_read_data_gv7601(struct file *pFile, command __user *pData, size_t count, loff_t *off)
{//加片选?printk("in the read function\n");unsigned short writecommand = 0x8000;memcpy(&temp,pData,count);writecommand = writecommand + temp.address;//SPI_send_gv7601(writecommand);//udelay(300);temp.value=spi_read_gv7601(writecommand);int ret;ret=copy_to_user(pData, &temp, sizeof(temp));    if(ret>0)  {  printk("copy data failed\n");  return -1;  }//spi_setlow(PIN_SCLK);return count;
}
static void set_value()
{ //初始化配置
} static int gv7601_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
{
return 0;
}static struct file_operations gv7601_fops = {
.owner = THIS_MODULE,
.compat_ioctl = gv7601_ioctl,
.read = spi_read_data_gv7601,
.write = spi_write_data_gv7601,
};  static int __init spi_gv7601_init(void)
{ int ret;  ret = register_chrdev(GV7601_MAJOR, DEVICE_NAME, &gv7601_fops);  if (ret < 0) {  printk(DEVICE_NAME " can't register major number\n");  return ret; }printk("Register spi control.\n"); spi_init_gv7601(); //reset the device//lowHi3516_gpio_setpin(IO_ADDRESS(GPIO1_BASE+(1<<8)),Hi3516_gpio_getpin(IO_ADDRESS(GPIO1_BASE+(1<<8)))&(~(1<<(8-2))));udelay(200);//highHi3516_gpio_setpin(IO_ADDRESS(GPIO1_BASE+(1<<8)),Hi3516_gpio_getpin(IO_ADDRESS(GPIO1_BASE+(1<<8)))|(1<<(8-2)));//spi_setcs_gv7601(1); //ndelay(20);     //set_value(); //spi_setcs_gv7601(2); return 0;
}
static void __exit spi_gv7601_exit(void)
{ unregister_chrdev(GV7601_MAJOR, DEVICE_NAME); printk(KERN_INFO "unregister spi control.\n"); }
module_init(spi_gv7601_init);
module_exit(spi_gv7601_exit);
MODULE_LICENSE("GSPI");
MODULE_AUTHOR("Dong 100");
MODULE_VERSION("0.1");
MODULE_DESCRIPTION("gv7601 control driver"); 
/*读取的测试程序*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <string.h>
typedef struct tem{
unsigned short address;
unsigned short value;
}command;
command temp;int main(int argc, char *argv[])
{//printf("~~~~%s~~~~~",argv[1]);//printf("....%c....",*argv[1]+1);//printf("the char size is %d",sizeof(char));//printf("the number is %d",strlen(argv[1]));if (argc<=1||argc>3){printf("wrong command \n ./test_spi 000 for read from 000H\n ./test_spi 000 0012 for write 0012 to adress 000H\n");return 0;}else if (argc==2){if (strlen(argv[1])>3){printf("address is too long, 12bits max");return 0;}char a;int i;unsigned short result=0;printf("read address command\n");for (i=1;i<=strlen(argv[1]);i++){        a=*(argv[1]+i-1);if (a>='0'&&a<='9')a=a-'0';else if (a>='a'&&a<='f')a=a-'a'+10;else if (a>='A'&&a<='F')a=a-'A'+10;else return 0;//printf("now a is %x",a);//j=strlen(argv[1])-i;result=result+a;if (i!=strlen(argv[1]))result=result<<4;}printf("read from address%x\n",result);int fd;fd = open("/dev/spi_g",2);printf("open fd is %d\n",fd);int ret;temp.address=result;temp.value=0x0000;ret=read(fd,&temp,sizeof(temp));printf("read value is %x\n",temp.value);}else{if (strlen(argv[1])>3){printf("address is too long, 12bits max");return 0;}if (strlen(argv[2])>4){printf("data is too long, 16bits max");return 0;}char a;int i;unsigned short result,result2=0;//printf("read address command");printf("write to address comand\n");result=0;for (i=1;i<=strlen(argv[1]);i++){        a=*(argv[1]+i-1);if (a>='0'&&a<='9')a=a-'0';else if (a>='a'&&a<='f')a=a-'a'+10;else if (a>='A'&&a<='F')a=a-'A'+10;else return 0;//printf("now a is %x",a);//j=strlen(argv[1])-i;result=result+a;if (i!=strlen(argv[1]))result=result<<4;}result2=0;for (i=1;i<=strlen(argv[2]);i++){        a=*(argv[2]+i-1);if (a>='0'&&a<='9')a=a-'0';else if (a>='a'&&a<='f')a=a-'a'+10;else if (a>='A'&&a<='F')a=a-'A'+10;else return 0;//printf("now a is %x",a);//j=strlen(argv[1])-i;result2=result2+a;if (i!=strlen(argv[2]))result2=result2<<4;}printf("write to address%x,data is %x\n",result,result2);int fd;fd = open("/dev/spi_g",2);printf("open fd is %d\n",fd);int ret;temp.address=result;temp.value=result2;ret=write(fd,&temp,sizeof(temp));//printf("read value is %x\n",temp.value);}return 0;}
/*Makefile*/
obj-m += ssp.o
all:    arm-hisiv300-linux-gcc -g -Wall -o ssp_test ssp_test.cmake ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- -C /home/zslf/hi3516a/Hi3516A_SDK_V1.0.5.0/osdrv/opensource/kernel/linux-3.4.y SUBDIRS=$(PWD) modulesrm *.o modules.* *.symvers *.mod.c
clean:@rm -rf ssp_test make ARCH=arm CROSS_COMPILE=arm-hisiv300-linux- -C /home/zslf/hi3516a/Hi3516A_SDK_V1.0.5.0/osdrv/opensource/kernel/linux-3.4.y SUBDIRS=$(PWD) clean

按源码执行会出现错误:

/home/zslf/hi3516a/Hi3516A_SDK_V1.0.5.0/tools_test/spi测试/ssp.c:334:1: error: unknown field ‘ioctl’ specified in initializer.ioctl = gv7601_ioctl,  ^

问题是由于2.6.36内核之后 去掉了原来的ioctl,添加两个新的成员,所以会出错
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
所以修改源文件中file_operations内.ioctl 改为 .compat_ioctl 即可OK,编译通过,警告咱就忽略了

Hi3516A开发--GV7601 硬件设计相关推荐

  1. Hi3516A开发--USB PCB 设计建议

    USB PCB 设计建议 为了保证良好的信号质量, USB 2.0 端口数据信号线按照差分线方式走线.为了达到USB 2.0 高速 480MHz 的速度要求,建议 PCB 布线设计采用以下原则: 差分 ...

  2. STM32F4主板硬件设计与接口

    更多交流欢迎关注作者抖音号:81849645041 本专栏的所有程序都在飞航科技 STM32-F407 开发板上测试通过,本文介绍一下STM32-F407 开发板硬件设计与接口,便于读者学习交流. S ...

  3. 用stm32开发时是直接买现成的开发板还是芯片?开发板学习,芯片硬件设计

    视情况而言,买开发板用于评估和学习,然后买芯片做硬件设计 开发板 开发板上手即可使用,并附带很多模块. 拿到开发板后即可直接根据开发板提供的原理图进行程序编写,学习. 优点:简单快捷,上手快,拿到手就 ...

  4. systemverilog硬件设计及建模_Chisel引领敏捷硬件开发浪潮

    转载一篇18年6月的旧文 众所周知,近来开源处理器项目RISC-V在半导体业界掀起了一片新的潮流.这股潮流同时带来的,还包括了敏捷芯片开发. "敏捷开发"对于IC设计工程师来说似乎 ...

  5. 嵌入式系统开发这六点硬件设计需要细心留意

    嵌入式设计是个庞大的工程,今天就说说硬件电路设计方面的几个注意事项,首先,咱们了解下嵌入式的硬件构架.我们知道,CPU是整个系统的灵魂,所有的外围配置都与其相关联,这也突出了嵌入式设计的一个特点硬件可 ...

  6. 硬件设计开发全套软件

    1.原理图与PCB设计:AD.Candence orcad capture cis和pcb editor AD,目前最常用的硬件设计工具,为中小型企业和学校学生所熟知,Protel的升级版. Cand ...

  7. 张飞电子工程师速成视频教程百度云_电气工程师张飞电子工程师速成 硬件设计与开发 视频教程 第二部 (价值98元) | 吾爱楼52Lou...

    教程名称:张飞电子工程师速成 硬件设计与开发 视频教程 第二部 课程简介: 张飞电子工程师速成 硬件设计与开发 视频教程 第二部 现场以循环泵系统项目为实际研发项目,教会大家学习硬件电路设计! 课程简 ...

  8. 【张飞实战电子】硬件设计与开发第1部:线性稳压电源的设计 笔记

    硬件设计与开发 初级 [张飞实战电子]硬件设计与开发第1部:线性稳压电源的设计 目标设计一款低成本线性稳压电源 LED的导通电压为3V3,电流为3mA~10mA,需要一个电源来提供,日常生活基本都是电 ...

  9. DDR3、DDR3L以及LPDDR3对比介绍,规范解读以及硬件设计开发实际案例分享

    本文主要是由一个问题引起,关于Zynq 7000系列芯片是否支持LPDDR3.Zynq7000是不支持LPDDR3应用的,还有一些特殊形式的Dual-die / Quad-die这种形式的DDR3颗粒 ...

最新文章

  1. hibernate多个主键
  2. 迁移Azure web site实践 (三),Azure web site迁移
  3. Visual Studio 快捷键使用方法
  4. MCMC 和 Gibbs采样
  5. pycharm python 模板配置_windows下pycharm安装、创建文件、配置默认模板
  6. 陈广老师 C#语言参考视频打包下载地址
  7. Maven运行报错:-Dmaven.multiModuleProjectDirectory system propery is not set.
  8. 飞机上一旅客突然收到生日蛋糕,是个小惊喜
  9. VMware虚拟机软件账号的注册问题
  10. 2015美国大学计算机科学专业排名,美国大学研究生计算机科学专业排名|2015年计算机科学专业排行榜(1/2)- 各国学校排名网...
  11. 图像空间和灰度分辨率
  12. 万马股份旗下万马爱充遭通报下架:违规收集个人信息,未及时整改
  13. 架构漫谈(八):从架构的角度看如何写好代码 + 我的思考
  14. 【算法练习】CodeVs1391 伊吹萃香(分层图最短路)
  15. PAT-2019年冬季考试-甲级-7-1 Good in C (20分)超详解,几招就满分通过
  16. app同质化趋势下,如何实现差异化?
  17. 旧书交易系统——第一次报告
  18. 充电宝系统连接不上服务器,苹果上架MagSafe磁吸充电宝,B站服务器机房故障造成无法访问...
  19. Geospatial Data Science (1):Introduction and Geometric objects
  20. java实现一元二次函数求解

热门文章

  1. linux下使用yum安装新版php7.0
  2. My Goal For SE
  3. 使Struts2与Servlet并存解决办法 Filter转发Servlet
  4. 解决:此错误(HTTP 500 内部服务器错误)意味着您正在访问的网站出现了服务器问题,此问题阻止了该网页的显示...
  5. 双指针解决数组排序问题
  6. Python学习笔记:高级特性
  7. Zero Copy 简介
  8. 希尔排序python实现
  9. TOPSIS(逼近理想解)算法原理详解与代码实现
  10. matlab按顺序排列图片,小技巧