SylixOS SPI 总线框架浅析

修订历史
版本 日期 原因
V1.00 2018/8/18 创建文档

目 录
1 SPI总线关键结构体 1
1.1 总线传输控制消息块 1
1.2 SPI总线适配器 2
1.3 SPI设备 3
2 SPI各个结构体之间的联系 3
2.1 总线链表 3
2.2 总线与设备 3
3 参考资料 4

1 SPI总线关键结构体
1.1 总线传输控制消息块
传输控制消息包括操作单位bits数、传输控制参数(时钟极性、相位和字节序等配置)、发送和接收缓冲区及其长度、传输结束的回调函数。如程序清单 1.1所示。
程序清单 1.1

typedef struct lw_spi_message {
    UINT16                   SPIMSG_usBitsPerOp;                        /*  操作单位bits数              */
    UINT16                   SPIMSG_usFlag;                             /*  传输控制参数                */

#define LW_SPI_M_CPOL_0      0x0000                                     /*  CPOL 配置                   */
#define LW_SPI_M_CPOL_1      0x0001
#define LW_SPI_M_CPHA_0      0x0000                                     /*  CPHA 配置                   */
#define LW_SPI_M_CPHA_1      0x0002

#define LW_SPI_M_CPOL_EN     0x0004                                     /*  是否设置新的 CPOL 配置      */
                                                                        /*  否则 CPOL 配置与上次传输相同*/
#define LW_SPI_M_CPHA_EN     0x0008                                     /*  是否设置新的 CPHA 配置      */
                                                                        /*  否则 CPHA 配置与上次传输相同*/

/*********************************************************************************************************
  LW_SPI_M_WRBUF_FIX, LW_SPI_M_RDBUF_FIX 主要用于半双工的 SPI 操作 (多数从机器件都是这种操作模式).

  1: 当 LW_SPI_M_WRBUF_FIX 有效时, 表明本次操作是读操作, 每次发送的数据都是 SPIMSG_pucWrBuffer 的第一个字
     符, 而读到的数据将依次存放在 SPIMSG_pucRdBuffer 中.
     所以: 读缓冲的大小必须可以存放 SPIMSG_usLen 个字符, 而写缓冲的大小可以仅是 1 个字符长度.
  2: 当 LW_SPI_M_RDBUF_FIX 有效时, 表明本次操作是写操作, 对读到什么数据并不感兴趣, 所以每次读到的数据都放
     在 SPIMSG_pucRdBuffer 的第一个字符处.
     所以: 写缓冲的大小必须可以存放 SPIMSG_usLen 个字符, 而读缓冲的大小可以仅是 1 个字符长度.
*********************************************************************************************************/

#define LW_SPI_M_WRBUF_FIX   0x0010                                     /*  发送缓冲区仅发送第一个字符  */
                                                                        /*  永远发送第一个字符          */
#define LW_SPI_M_RDBUF_FIX   0x0020                                     /*  接收缓冲区仅接收第一个字符  */
                                                                        /*  接收的数据永远发在第一个接收*/
                                                                        /*  缓冲指针的位置              */

#define LW_SPI_M_MSB         0x0040                                     /*  从高位到低位                */
#define LW_SPI_M_LSB         0x0080                                     /*  从低位到高位                */

    UINT32                   SPIMSG_uiLen;                              /*  长度(缓冲区大小)            */
                                                                        /*  长度为0, 只设置传输控制参数 */

    UINT8                   *SPIMSG_pucWrBuffer;                        /*  发送缓冲区                  */
    UINT8                   *SPIMSG_pucRdBuffer;                        /*  接收缓冲区                  */

    VOIDFUNCPTR              SPIMSG_pfuncComplete;                      /*  传输结束后的回调函数        */
    PVOID                    SPIMSG_pvContext;                          /*  回调函数参数                */
} LW_SPI_MESSAGE;

1.2 SPI总线适配器
总线设配器包括总线节点、总线适配器操作函数、总线操作锁和设备链表。如程序清单 1.2所示。总线节点是用于管理所有SPI总线的链表节点;总线适配器操作函数包括总线传输函数和总线控制函数;总线操作锁用于实现总线互斥操作;设备链表是由所有关联当前SPI适配器的设备组成的链表。
程序清单 1.2

typedef struct lw_spi_adapter {
    LW_BUS_ADAPTER           SPIADAPTER_pbusadapter;     /*  总线节点 */
    struct lw_spi_funcs     *SPIADAPTER_pspifunc;        /* 总线适配器操作函数 */
    LW_OBJECT_HANDLE         SPIADAPTER_hBusLock;         /*  总线操作锁*/
    LW_LIST_LINE_HEADER      SPIADAPTER_plineDevHeader;      /*  设备链表  */

} LW_SPI_ADAPTER;
typedef struct lw_spi_funcs {
    INT              (*SPIFUNC_pfuncMasterXfer)(PLW_SPI_ADAPTER   pspiadapter,
                                                      PLW_SPI_MESSAGE   pspimsg,
                                                      INT               iNum);
                                                   /*  适配器数据传输              */
    INT              (*SPIFUNC_pfuncMasterCtl)(PLW_SPI_ADAPTER   pspiadapter,
                                                     INT               iCmd,
                                                     LONG              lArg);
                                                      /*  适配器控制                  */
} LW_SPI_FUNCS;

1.3 SPI设备
SPI设备结构成员包括挂载的适配器指针、设备挂载链、设备使用计数、设备名称。如程序清单 1.3所示。
程序清单 1.3

typedef struct lw_spi_device {
    PLW_SPI_ADAPTER              SPIDEV_pspiadapter;   /*  挂载的适配器 */
    LW_LIST_LINE                 SPIDEV_lineManage;     /*  设备挂载链   */
    atomic_t                     SPIDEV_atomicUsageCnt; /*  设备使用计数 */
    CHAR                         SPIDEV_cName[LW_CFG_OBJECT_NAME_SIZE]; /*  设备的名称                  */
} LW_SPI_DEVICE;

2 SPI各个结构体之间的联系
2.1 总线链表
所有SPI总线适配器都是链接在以_G_plineBusAdapterHeader为头节点的链表上。如图 2.1所示。

图 2.1 SPI总线链表
2.2 总线与设备
总线与设备的逻辑关系如图 2.2所示。

图 2.2 总线与设备关系
3 参考资料
《SylixOS_driver_usermanual》

原文地址:http://blog.51cto.com/12142768/2170557

时间: 2024-11-10 10:51:18

SylixOS SPI 总线框架浅析的相关文章

SylixOS CAN总线报文浅析

CAN的报文格式 在总线中传送的报文,每帧由7部分组成.CAN协议支持两种报文格式,其唯一的不同是标识符(ID)长度不同,标准格式为11位,扩展格式为29位. 在标准格式中,报文的起始位称为帧起始(SOF),然后是由11位标识符和远程发送请求位(RTR)组成的仲裁场.RTR位标明是数据帧还是请求帧,在请求帧中没有数据字节. 控制场包括标识符扩展位(IDE),指出是标准格式还是扩展格式.它还包括一个保留位 (ro),为将来扩展使用.它的最后四个位用来指明数据场中数据的长度(DLC).数据场范围为0

SylixOS NUC970平台SPI总线数据传输

概述 本文档是对NUC970平台上的SylixOS SPI总线数据传输的详细分析. SPI总线数据传输流程 NUC970平台上SPI总线数据传输流程如图 21所示. 当一个消息准备传输时,第一步判断发送和接收缓存区是否为空,若为空,就没有要接收或发送的数据,直接返回. 第二步,判断消息长度是否大于指定的值(可以改变,但要大于16个字节),若大于,以16字节为单位传输数据,否则以单字节为单位传输数据. 图21 SPI数据传输流程图 SPI总线的消息类型 在SylixOS中,SPI总线的消息类型,如

Android Otto框架浅析

今天要介绍的是一个Android中使用得比較多的android 事件总线 EventBus模式的一个框架Otto. Otto 官网:http://square.github.io/otto/ 一.Android Studio中配置Otto (Eclipse中直接下载jar包导入) 跟之前介绍的其它的框架一样,它只须要简单地在build.gradle中配置以下一行红色字体就可以 dependencies {    compile fileTree(dir: 'libs', include: ['*

Linux SPI总线和设备驱动架构之一:系统概述【转】

转自:http://blog.csdn.net/droidphone/article/details/23367051/ 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 硬件结构 工作时序 软件架构 SPI控制器驱动程序 SPI通用接口封装层 SPI协议驱动程序 SPI通用设备驱动程序 SPI是"Serial Peripheral Interface" 的缩写,是一种四线制的同步串行通信接口,用来连接微控制器.传感器.存储设备,SPI设备分为主设备和从设备两种,

Linux SPI总线和设备驱动架构之四:SPI数据传输的队列化

我们知道,SPI数据传输可以有两种方式:同步方式和异步方式.所谓同步方式是指数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用传输的函数后,直到数据传输完成,函数才会返回.而异步方式则正好相反,数据传输的发起者无需等待传输的结束,数据传输期间还可以做其它事情,用代码来解释就是,调用传输的函数后,函数会立刻返回而不用等待数据传输完成,我们只需设置一个回调函数,传输完成后,该回调函数会被调用以通知发起者数据传送已经完成.同步方式简单易用,很适合处理那些少量数据的单次传

Linux SPI总线和设备驱动架构之三:SPI控制器驱动

通过第一篇文章,我们已经知道,整个SPI驱动架构可以分为协议驱动.通用接口层和控制器驱动三大部分.其中,控制器驱动负责最底层的数据收发工作,为了完成数据的收发工作,控制器驱动需要完成以下这些功能:1.    申请必要的硬件资源,例如中断,DMA通道,DMA内存缓冲区等等:2.    配置SPI控制器的工作模式和参数,使之可以和相应的设备进行正确的数据交换工作: 3.    向通用接口层提供接口,使得上层的协议驱动可以通过通用接口层访问控制器驱动: 4.    配合通用接口层,完成数据消息队列的排

Linux SPI总线和设备驱动架构之一:系统概述

SPI是"Serial Peripheral Interface" 的缩写,是一种四线制的同步串行通信接口,用来连接微控制器.传感器.存储设备,SPI设备分为主设备和从设备两种,用于通信和控制的四根线分别是: CS    片选信号 SCK  时钟信号 MISO  主设备的数据输入.从设备的数据输出脚 MOSI  主设备的数据输出.从设备的数据输入脚 因为在大多数情况下,CPU或SOC一侧通常都是工作在主设备模式,所以,目前的Linux内核版本中,只实现了主模式的驱动框架. /*****

事件总线框架---Otto

我们假设这样一种业务场景,现在在做一款及时聊天应用,我们在聊天页面进行收发信息,同时也要实时更新前一页面的聊天记录,这时我们该如何去实现?说说我以前的实现策略,我使用的是广播接收器BroadCastReceiver,在接收和发送消息的时候就不停去发送广播,然后在需要实时更新的地方进行接收更新.实现的思想比较简单,也不存在代码上的耦合问题,但是有个弊端.弊端就是需要去在很多地方实现BroadCastRecevier,代码虽不算冗余,但比较多,看起来很是不爽. 今天为大家介绍的Otto,就能彻底解决

【转载】DXUT11框架浅析(4)--调试相关

原文:DXUT11框架浅析(4)--调试相关 DXUT11框架浅析(4)--调试相关 1. D3D8/9和D3D10/11的调试区别 只要安装了DXSDK,有个调试工具DirectX ControlPanel,如下图所示.这里可以将Direct3D 9设置为调试运行时(Debug D3D9 Runtime)或零售运行时(RetailD3D9 Runtime).注意这里的设置是全局的,如果改成调试运行时,则所有用到D3D9的程序都会进入调试模式,这会使这些程序运行的很慢. 从Vista开始系统自己