当前位置: 首页 > news >正文

全志SPI-NG框架使用说明

一、简介

SPI-NG框架,NG为next generation的缩写,是全志新的SPI框架,在新的BSP包中已全部启用。支持SPI 主从模式的配置和使用。

二、设备树配置

sunxi,spi-bus-mode = <SUNXI_SPI_BUS_MASTER>;

有两个选项:

  • SUNXI_SPI_BUS_MASTER
  • SUNXI_SPI_BUS_SLAVE

驱动默认配置为:SUNXI_SPI_BUS_MASTER,当选为SUNXI_SPI_BUS_SLAVE模式时,还可进行SLAVE详细的配置。

dma0:dma-controller@03002000 {compatible = "allwinner,sun8i-dma";reg = <0x0 0x03002000 0x0 0x1000>;interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clk_dma>;#dma-cells = <1>;dma-channels = <24>;   //打开SPI相应通道的DMAdma-requests = <64>;status = "okay";
};
spi1: spi@05011000 {#address-cells = <1>;#size-cells = <0>;compatible = "allwinner,sunxi-spi-v0.91";device_type = "spi1";reg = <0x0 0x05011000 0x0 0x1000>;interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clk_pll_periph0>, <&clk_spi1>;clock-names = "pll", "mod", "ahb";clock-frequency = <100000000>;pinctrl-names = "default", "sleep";pinctrl-0 = <&spi1_pins_a &spi1_pins_b>;pinctrl-1 = <&spi1_pins_c>;use_dma = <1>;dmas = <&dma0 23>, <&dma0 23>;dma-names = "tx", "rx";sunxi,spi-num-cs = <2>;sunxi,spi-bus-mode = <SUNXI_SPI_BUS_SLAVE>;sunxi,spi-slave-cs = <0>;sunxi,spi-slave-mode = <SUNXI_SPI_SLAVE_CYCLIC_MODE>;sunxi,spi-cs-mode = <0>;  //0 auto, 1 softstatus = "disabled";
};
sunxi,spi-slave-mode = <SUNXI_SPI_SLAVE_CYCLIC_MODE>;

SLAVE的方式有两个选项:

  • SUNXI_SPI_SLAVE_GENERAL_MODE
  • SUNXI_SPI_SLAVE_CYCLIC_MODE

驱动默认配置为SUNXI_SPI_SLAVE_GENERAL_MODE

SUNXI_SPI_SLAVE_GENERAL_MODE 为普通的模式,可以用来作为从设备的数据收发。SUNXI_SPI_SLAVE_CYCLIC_MODE 为DMA回环模式,只能用来作为数据的接收,不间断的接收。

三、驱动初始化调用流程

sunxi_spi_init()platform_driver_register()sunxi_spi_probe()                    //生成struct sunxi_spi *sspi结构体dma_set_mask_and_coherent()        //设置 DMA 掩码以告知内核 设备 DMA 寻址功能dma_set_max_seg_size()            //设备定义单次 DMA 传输的最大字节数,这里配置的是页大小,4KBsunxi_spi_resource_get()        //获取设备树资源,字段一一获取spi_alloc_master()sunxi_spi_request_dma()            //获取DMA的收发通道sunxi_spi_hw_init()                //硬件配置,包括配置寄存器,时钟,配置为从模式等spi_register_master()            //注册SPI控制器,后面的SPI操作就用这个控制器中的函数了sunxi_spi_create_cyclic_dev()    //如果是SLAVE_CYCLIC_MODE设备,则创建相关设备

sunxi_spi_probe函数执行过程:

sunxi_spi_probe()sunxi_spi_resource_get                (获取设备树资源配置)这里有一个获取ready-gpio的配置//这里进行相关函数的配置sspi->ctlr->prepare_message        = sunxi_spi_prepare_message;sspi->ctlr->unprepare_message    = sunxi_spi_unprepare_message;sspi->ctlr->setup            = sunxi_spi_setup;sspi->ctlr->set_cs            = sunxi_spi_set_cs;if (sspi->use_dma)sspi->ctlr->can_dma        = sunxi_spi_can_dma;sspi->ctlr->transfer_one    = sunxi_spi_transfer_one;sspi->ctlr->handle_err        = sunxi_spi_handle_err;ret = devm_request_irq(sspi->dev, sspi->irq, sunxi_spi_handler, 0, dev_name(sspi->dev), sspi);    //spi本身自己的中断gpio_direction_output(sspi->ready_gpio, 0);    //将这个引脚电平输出为低。

ready-gpio这个脚就是用来做同步的,主要解决主从双方何时收发数据。 如果没有这个GPIO脚,就是双方自己约定一个休眠时间,发完数据后等待一段时间再处理。

四、主模式(master)数据收发流程

1、发送数据

sunxi_spi_transfer_one()sunxi_spi_xfer_master()                        (mode_type : SINGLE_HALF_DUPLEX_TX - 2)sunxi_spi_dma_tx()                        //如果符合使用DMA的条件则使用DMA传输sunxi_spi_start_xfer()                    //开启传输sunxi_spi_cpu_tx()                        //如果不符合使用DMA的条件则使用CPU传输wait_for_completion_timeout()            //等待数据传输完成sunxi_spi_dma_cb_tx()                //如果DMA传输则调这个函数,什么也没有做sunxi_spi_handler()sunxi_spi_bus_handler()            //将done complete,唤醒wait操作

2、接收数据

sunxi_spi_transfer_one()sunxi_spi_xfer_master()                        (mode_type : SINGLE_HALF_DUPLEX_RX - 1)sunxi_spi_dma_rx()                        //如果符合使用DMA的条件则使用DMA传输sunxi_spi_start_xfer()sunxi_spi_cpu_rx()                        //如果不符合使用DMA的条件则使用CPU传输wait_for_completion_timeout()            //等待数据传输完成sunxi_spi_dma_cb_rx()                //如果DMA传输则调这个函数,将done complete,唤醒wait操作sunxi_spi_handler()sunxi_spi_bus_handler()            //如果CPU传输将done complete,唤醒wait操作

五、从模式(slave)数据收发流程

1、接收数据

sunxi_spi_transfer_one()sunxi_spi_xfer_slave()                        (mode_type : SINGLE_HALF_DUPLEX_RX - 1)sunxi_spi_dma_rx()                        //如果符合使用DMA的条件则使用DMA传输sunxi_spi_enable_irq()                    //如果不符合则使能数据ready中断wait_for_completion_interruptible()        //等待数据传输完成sunxi_spi_dma_cb_rx()                //如果DMA传输完则调这个函数,将done complete,唤醒wait操作sunxi_spi_handler()sunxi_spi_bus_handler()            //将done complete,唤醒wait操作sunxi_spi_cpu_rx()                        //如果不符合使用DMA的条件则使用CPU传输

注意:如果是SUNXI_SPI_SLAVE_CYCLIC_MODE模式则不等待数据接收完毕,直接返回了,也就是不会调用wait_for_completion_interruptible函数

2、发送数据

sunxi_spi_transfer_one()sunxi_spi_xfer_slave()                        (mode_type : SINGLE_HALF_DUPLEX_TX - 2)sunxi_spi_dma_tx()                        //如果符合使用DMA的条件则使用DMA传输sunxi_spi_enable_irq()                    //使能数据发送完成中断wait_for_completion_interruptible()        //等待数据传输完成sunxi_spi_dma_cb_tx()                //如果DMA传输则调这个函数,什么也没有做sunxi_spi_handler()sunxi_spi_bus_handler()            //将done complete,唤醒wait操作

3、GENERAL_MODE模式

全志提供了spi-sunxi-slave-test.c 设计了一个简单的方案,针对主机先发送操作码,然后发送数据给从机,从机将这个数据存到一个cache中,并通过sys接口给上层去访问。

有个packet head结构,如下:

struct sunxi_spi_slave_head {u8 op_code;                            //代表操作码u8 bits;                            //SPI_NBITS_SINGLE 单bit位传输u16 addr;                            //要操作的地址u16 len;                            //数据的长度
};
{ 0x03 0x01 0x00 0x00 0x00 0x20 }

op_code类型:

#define SUNXI_OP_WR            0x01        /* 这里其实是全双工的方式,MOSI和MISO均有数据 */
#define SUNXI_OP_RD            0x02
#define SUNXI_OP_WR_RD        0x03        /* 这里其实是全双工的方式,MOSI和MISO均有数据 */
#define SUNXI_OP_HEAD        0xff        /* Only used in kernel space */

数据收发流程:

sunxi_spi_slave_test_submit()                                //spi-sunxi-slave-test.csunxi_spi_transfer_one()                                //spi-ng/spi-sunxi.csunxi_spi_xfer_slave()wait_for_completion_interruptible()                //一直等待数据传输完sunxi_spi_cpu_rx()                                //有数据后从寄存器中进行拷贝sunxi_spi_slave_test_complete()                            //spi-sunxi-slave-test.c (数据传输完,到达complete,此时可以将数据拷贝的驱动的其位置)sunxi_spi_slave_test_submit()                            //开始下一轮的数据获取

测试命令:

(在主设备中运行)半双工收发测试

./spidev_test -D /dev/spidev1.0 -s 10000000 -S 32 -I 1 -v -H -O

从设备中执行如下命令,查看收到的数据

hexdump -C /sys/devices/platform/soc/spi1/spi_master/spi1/spi1.0/sunxi-slave-test

4、CYCLIC_MODE模式

DMA环形设备 sunxi_spi_create_cyclic_dev,在选择这个模式时会自动创建该设备,对应的操作函数如下:

static const struct file_operations spi_cyclic_dev_fops =
{.open = spi_cyclic_dev_open,.release = spi_cyclic_dev_release,.unlocked_ioctl = spi_cyclic_dev_ioctl,.mmap = spi_cyclic_dev_mmap,
};

上层操作如下:

spi_cyclic_dev_ioctl()SPI_CYCLIC_DEV_START设置定时器的timeout创建spi device开始传输数据sunxi_spi_slave_cyclic_dev_hrtimer_handler()       //定时执行函数
DMA设定传输的字节数为t->len,PAGE_SIZE,4096字节
dmaengine_tx_status       //查看当前传输的状态,state.residue返回剩余传输字节数
current_pos               //为当前传输了多少数据
rx_last_pos               //上次传输了多少数据如果current_pos不等于rx_last_pos
【1】 如果current_pos大于rx_last_pos,说明有新的数据过来了
【2】 如果current_pos小于rx_last_pos,说明DMA传输完了,存在数据覆盖了sspi->cyclic_dev->t->len - sspi->cyclic_dev->rx_last_pos  //上次剩余传输的字节数
sspi->cyclic_dev->buf_size - sspi->cyclic_dev->buf_pos    //缓冲区空间剩余的空间sspi->cyclic_dev->buf_size       //这是用户设定的大小,测试程序设置的是64KB
sspi->cyclic_dev->user_buf       //这是分配的缓冲区
sspi->cyclic_dev->buf_pos        //这是缓冲区的当前位置//更新位置
sspi->cyclic_dev->buf_pos += op_len;
sspi->cyclic_dev->rx_last_pos += op_len;总的来说就是不停的接收数据,并把数据放到用户缓冲区中去。
hrtimer_forward_now()            //启动下一轮定时器

针对这个设备,全志提供了一个测试程序spislave-cyclic-test,对应源代码为:spislave-cyclic-test.c使用命令为(在从设备中运行10us的定时器):

./spislave-cyclic-test -D /dev/spi1_cyclic_dev -t 10000

http://www.dtcms.com/a/557503.html

相关文章:

  • 域名及网站建设实训wordpress 不能自定义主题
  • 新河网站网站后台默认用户名
  • 第十二章:终极叩问:我是谁,我往何方?(1)
  • JAVA高频面试题
  • 如何制作一个自己的网站?安全教育平台登录入口网址
  • 软考 系统架构设计师系列知识点之杂项集萃(184)
  • Redis性能提升秘籍:大Key与热点Key优化实战
  • 大专物流管理专业职业发展指南
  • 徐州网站制作机构做猎头需要用到的网站
  • 石家庄做网站制作公司做公司点评的网站
  • Git指令集
  • 基于边缘信息提取的遥感图像开放集飞机检测方法
  • 前端基础知识---Promise
  • Java 基础——函数式编程
  • webkitx(Android WebView 最佳实践库)
  • 调查网站做调查不容易过横栏建设网站
  • 勐海县住房和城乡建设局网站南昌做网站费用
  • 感知上下文并可解释地预测合成致死药物靶点的大语言模型研究
  • AI研究-117 特斯拉 FSD 视觉解析:多摄像头 - 3D占用网络 - 车机渲染,盲区与低速复杂路况安全指南
  • 二级域名可以做网站吗免费个人博客网站模板下载
  • 复原大唐3d项目测试版
  • 2024年MySQL 下载、安装及启动停止教程(非常
  • 兰州百度网站建设百度网站关键词优化在哪里做
  • Redis——Windows安装
  • 微信网站开发视频教程免费的黄金软件
  • 【高级机器学习】0. Machine Learning 介绍
  • 昆明城乡和住房建设局网站网站做5级分销合法吗
  • .NETCore、.NET 7 和 RabbitMQ 的发布-订阅模式
  • Crashpad 在windows下编译和使用指南
  • 基于SpringBoot+Vue的农产品销售系统【协同过滤推荐算法+可视化统计】