SPI设备介绍
2.1 SPI-Flash设备原理图查看
1、SPI Nor Flash是Nor Flash的一种,Nor Flash是一种非易失闪存技术;
2、实验箱上带有一个SPI通信的Nor Flash,型号为25VF016B;
3、Nor Flash设备接在SPI0通道上,片选引脚为CS0。
1、CSPI1_CLK连接在CPU的EIM_D16引脚
2、CSPI1_MISO连接在CPU的EIM_D17引脚
3、CSPI1_MOSI连接在CPU的EIM_D18引脚
4、CSPI1_CS0连接在CPU的EIM_EB2引脚
2.2 SPI-Flash设备数据手册查看
2.2.1 擦除流程
1、发送擦除命令
2、发送想要擦除的地址
3、固定擦除4K大小
2.2.2 写流程
1、发送写命令
2、发送想要写的地址
3、发送想要写的数据
2.2.3 读流程
1、发读命令
2、发送想要读的地址
3、表明要读取的字节数
SylixOS下SPI总线驱动
3.1 创建SPI总线适配器
#include <SylixOS.h>
INT API_SpiAdapterCreate (CPCHAR pcName,
PLW_SPI_FUNCS pspifunc)
函数API_SpiAdapterCreate原型分析:
-
此函数成功返回ERROR_NONE,失败返回PX_ERROR;
-
参数pcName是SPI适配器的名称,即shell命令buss显示的名称;
-
参数pspifunc是SPI总线传输函数的指针。
-
例:API_SpiAdapterCreate("/bus/spi/0", pSpiFuncs);
3.2 SPI总线操作集
#include <SylixOS.h>
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;
typedef LW_SPI_FUNCS *PLW_SPI_FUNCS;
函数API_SpiAdapterCreate使用结构体PLW_SPI_FUNCS来向内核提供传输函数集合,其详细描述如下:
-
SPIFUNC_pfuncMasterXfer:SPI传输函数,SPI设备会直接调用此函数实现消息发送。第一个参数pspiadapter为SPI总线适配器指针,第二个参数pspimsg为SPI设备需要传输的消息结构体首地址指针,第三个参数iNum为需要传输的消息个数,以上三个参数即可告知SPI设备如何调用此函数实现消息传输;
-
SPIFUNC_pfuncMasterCtl:SPI适配器控制函数,用来实现与硬件控制器相关的控制。第一个参数pspiadapter为SPI总线适配器指针,第二个参数iCmd为控制命令,第三个参数lArg与iCmd相关。
3.3 SPI传输的消息结构体
SPI消息结构体是SPI主机和从机通信的消息格式,该结构体的详细描述如下:
#include <SylixOS.h>
typedef struct lw_spi_message {
UINT16 SPIMSG_usBitsPerOp; /* 操作单位bits数 */
UINT16 SPIMSG_usFlag; /* 传输控制参数 */
UINT32 SPIMSG_uiLen; /* 长度(缓冲区大小) */
/* 长度为0, 只设置传输控制参数 */
UINT8 *SPIMSG_pucWrBuffer; /* 发送缓冲区 */
UINT8 *SPIMSG_pucRdBuffer; /* 接收缓冲区 */
VOIDFUNCPTR SPIMSG_pfuncComplete; /* 传输结束后的回调函数 */
PVOID SPIMSG_pvContext; /* 回调函数参数 */
} LW_SPI_MESSAGE;
typedef LW_SPI_MESSAGE *PLW_SPI_MESSAGE;
-
SPIMSG_usBitsPerOp:操作单位bits数;
-
SPIMSG_usFlag:传输控制参数,其取值见表 1.2;
-
SPIMSG_usLen:存放消息内容的缓存区长度,若长度为0,只设置传输控制参数;
-
SPIMSG_pucWrBuffer:发送缓存区;
-
SPIMSG_pucusRdBuffer:接收缓存区;
-
SPIMSG_pfuncComplete:传输结束后的回调函数;
-
SPIMSG_pvContext:回调函数参数;
表 1.2传输控制参数表
传输控制参数取值 |
含义 |
LW_SPI_M_CPOL_0 LW_SPI_M_CPOL_1 |
CPOL配置 |
LW_SPI_M_CPHA_0 LW_SPI_M_CPHA_1 |
CPHA配置 |
LW_SPI_M_CPOL_EN |
是否设置新的CPOL配置 |
LW_SPI_M_CPHA_EN |
是否设置新的CPHA配置 |
LW_SPI_M_WRBUF_FIX |
|
LW_SPI_M_RDBUF_FIX |
接收缓存区仅接收第一个字节 |
LW_SPI_M_MSB |
从高位到低位 |
LW_SPI_M_LSB |
从低位到高位 |
SylixOS下SPI设备驱动
4.1 创建SPI设备
SPI flash是一个挂载在SPI总线上的设备,它依靠SPI总线的传输函数传递数据。所以在SPI flash设备创建时,要调用API_SpiDeviceCreate函数将其挂载在一个指定的SPI总线适配器上,具体实现如下程序清单所示。函数API_SpiDeviceCreate原型如下:
#include <SylixOS.h>
INT API_SpiDeviceTransfer (PLW_SPI_DEVICE pspidevice,
PLW_SPI_MESSAGE pspimsg,
INT iNum)
函数API_I2cDeviceTransfer原型分析:
-
此函数成功返回pspidevice(SPI设备结构体类型),失败返回LW_NULL;
-
参数pcAdapterName是设备挂载的SPI适配器名称;
-
参数pcDeviceName是设备名称。
-
例: API_SpiDeviceCreate("/bus/spi/0", "/dev/spiflash");
4.2 传输SPI消息
SPI flash需要调用SPI的传输函数API_SpiDeviceTransfer来完成数据的传输,函数API_SpiDeviceTransfer的原型如下:
#include <SylixOS.h>
INT API_SpiDeviceTransfer (PLW_SPI_DEVICE pspidevice,
PLW_SPI_MESSAGE pspimsg,
INT iNum)
函数API_SpiDeviceTransfer原型分析:
-
此函数成功返回ERROR_NONE,失败返回PX_ERROR;
-
参数pspidevice是SPI设备结构体;
-
参数 pspimsg是SPI传输消息结构体组;
-
参数 iNum是SPI传输消息数量。
-
例:传输SPI消息
/***************************************************************************
** 函数名称: __flashNorCmd1byte
** 功能描述: 写Spi_Flash 1Byte cmd
** 输 入 : ucCmd 控制命令
** 输 出 : NONE
** 返 回 : ERROR_CODE
***************************************************************************/
static INT __flashNorCmd1byte (UINT8 ucCmd)
{
UINT8 ucTxCmd[1] = {ucCmd};
LW_SPI_MESSAGE spiCmdMessage = {
.SPIMSG_uiLen = 1,
.SPIMSG_pucWrBuffer = ucTxCmd,
.SPIMSG_pucRdBuffer = NULL,
};
API_SpiDeviceTransfer(_G_spiNorObj.pSpiNorDev, &spiCmdMessage, 1);
/* 发起传输 */
return (ERROR_NONE);
}
SPI总线和SPI设备之间的联系纽带如下图: