SPI驱动分总线驱动及适配器驱动,和SPI子设备驱动。
下面是sylixos下的imxRT1050的SPI总线驱动源码.
/*********************************************************************************************************
**
** 中国软件开源组织
**
** 嵌入式实时操作系统
**
** SylixOS(TM)
**
** Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文 件 名: spi.c
**
** 创 建 人: Jiang.Heng(蒋恒)
**
** 文件创建日期: 2017 年 12 月 26 日
**
** 描 述: IMRT1050 处理器 SPI 总线驱动
*********************************************************************************************************/
#define __SYLIXOS_KERNEL
#include <SylixOS.h>
#include <module.h>
#include "linux/compat.h"
#include "spi.h"
#include "fsl_clock.h"
#include "fsl_lpspi.h"
#include "fsl_gpio.h"
#include "fsl_iomuxc.h"
#include "pinmux/pinmux.h"
#include "clk/clk.h"
#include "config.h"
/*********************************************************************************************************
SPI总线其他的宏定义
*********************************************************************************************************/
#define SPI_DEBUG(fmt, arg...) printk("[SPI] %s() : "fmt, __func__, ##arg)
/* 调试打印信息 */
#define SPI_CHANNEL_NUM (4) /* SPI总线数量 */
#define SPI_CHANNEL_0 (0) /* SPI0通道号 */
#define SPI_CHANNEL_1 (1) /* SPI1通道号 */
#define SPI_CHANNEL_2 (2) /* SPI2通道号 */
#define SPI_CHANNEL_3 (3) /* SPI3通道号 */
#define BAUDRATE_DEFAULT (500000) /* 默认波特率 500 KHZ */
#define NSEC (1000000000) /* 纳秒换算 */
#define TIMEOUT (1600) /* pend 超时时间 */
#define SPI_TIMEOUT (1000000) /* 超时时间 */
#define LPSPI_CLOCK_SOURCE_DIVIDER (7) /* 时钟源分频系数 */
#define LPSPI_CLOCK_SOURCE_SELECT (1) /* LPSPI 时钟源选择 */
#define LPSPI_CLOCK_FREQ \
(CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (LPSPI_CLOCK_SOURCE_DIVIDER + 1U))
/* 获得 LPSPI 时钟频率 */
#define LPSPI_MASTER_CLOCK_FREQ (LPSPI_CLOCK_FREQ) /* LPSPI 时钟频率 */
#define LPSPI_INT_PRIORITY (0xe) /* LPSPI 中断优先级 */
/*********************************************************************************************************
控制命令
*********************************************************************************************************/
#define SPI_M_CPOL_0 (0x0000) /* CPOL 配置 */
#define SPI_M_CPOL_1 (0x0001) /* CPOL 配置 */
#define SPI_M_CPHA_0 (0x0000) /* CPHA 配置 */
#define SPI_M_CPHA_1 (0x0002) /* CPOL 配置 */
#define SPI_M_PCS_MASK (0x0300) /* PCS 配置 */
#define SPI_M_PCS_SHIFT (8) /* PCS 移位 */
#define SPI_M_PCS_0 (0x0000) /* 片选0 */
#define SPI_M_PCS_1 (0x0100) /* 片选1 */
#define SPI_M_PCS_2 (0x0200) /* 片选2 */
#define SPI_M_PCS_3 (0x0300) /* 片选3 */
/*********************************************************************************************************
控制命令结构体定义
*********************************************************************************************************/
typedef struct spi_arg {
ULONG SPI_ulBaud; /* 波特率 */
UINT8 SPI_ucFlags; /* 传输控制参数 */
}SPI_ARG;
typedef struct spi_arg *PSPI_ARG;
/*********************************************************************************************************
SPI通道类型定义
*********************************************************************************************************/
struct spi_channel{
UINT32 SPI_uiChannel; /* 通道号 */
UINT32 SPI_uiIntVector; /* 中断号 */
BOOL SPI_bIsInit; /* 是否进行控制器初始化标志 */
LW_OBJECT_HANDLE SPI_hSignal; /* 句柄 */
UINT SPI_uiRemainingBytes; /* 消息剩余大小 */
PLW_SPI_MESSAGE SPI_pMsg; /* 消息队列 */
UINT32 SPI_uiFifoSize; /* SPI FIFO 大小 */
};
typedef struct spi_channel __SPI_CHANNEL;
typedef struct spi_channel *__PSPI_CHANNEL;
/*********************************************************************************************************
全局变量
*********************************************************************************************************/
static __SPI_CHANNEL _G_spiChannels[SPI_CHANNEL_NUM] = {
{
SPI_CHANNEL_0, /* SPI0 通道号 */
BSP_IRQ_TO_VECTOR(LPSPI1_IRQn), /* SPI0 中断号 */
},
{
SPI_CHANNEL_1, /* SPI0 通道号 */
BSP_IRQ_TO_VECTOR(LPSPI2_IRQn), /* SPI0 中断号 */
},
{
SPI_CHANNEL_2, /* SPI0 通道号 */
BSP_IRQ_TO_VECTOR(LPSPI3_IRQn), /* SPI0 中断号 */
},
{
SPI_CHANNEL_3, /* SPI0 通道号 */
BSP_IRQ_TO_VECTOR(LPSPI4_IRQn), /* SPI0 中断号 */
},
};
/*********************************************************************************************************
** 函数名称: __spiBaseGet
** 功能描述: 获得 SPI 基址
** 输 入 : uiChannel SPI 通道号
** 输 出 : NONE
** 返 回 : NONE
*********************************************************************************************************/
static LW_INLINE LPSPI_Type *__spiBaseGet (UINT32 uiChannel)
{
switch (uiChannel) {
case SPI_CHANNEL_0:
return (LPSPI1);
case SPI_CHANNEL_1:
return (LPSPI2);
case SPI_CHANNEL_2:
return (LPSPI3);
case SPI_CHANNEL_3:
return (LPSPI4);
default:
SPI_DEBUG("channel num is error\n");
return (LPSPI1);
}
}
/*********************************************************************************************************
** 函数名称: __spiDataReceive
** 功能描述: SPI 接收数据函数
** 输 入 : pSpiChannel SPI 通道
** 输 出 : NONE
** 返 回 : NONE
*********************************************************************************************************/
static VOID __spiDataReceive (__PSPI_CHANNEL pSpiChannel)
{
PLW_SPI_MESSAGE pSpimsg = pSpiChannel->SPI_pMsg; /* 传输控制消息 */
UINT32 uiChannel = pSpiChannel->SPI_uiChannel; /* 获取通道号 */
UINT32 uiPosition = pSpimsg->SPIMSG_uiLen - pSpiChannel->SPI_uiRemainingBytes;
/* 当前消息的位置 */
UINT8 *pucRxbuf = pSpimsg->SPIMSG_pucRdBuffer; /* 接收数据缓存区 */
UINT8 *pucBytes = (UINT8 *)(pucRxbuf + uiPosition);
UINT32 uiNumBytes;
UINT32 uiRd; /* 保存 RDR 寄存器的值 */
uiNumBytes = LPSPI_GetRxFifoCount(__spiBaseGet(uiChannel)); /* 当前接收FIFO中消息的数量 */
/*
* 更新消息剩余大小
*/
if (pSpiChannel->SPI_uiRemainingBytes > uiNumBytes) {
pSpiChannel->SPI_uiRemainingBytes -= uiNumBytes;
} else {
pSpiChannel->SPI_uiRemainingBytes = 0; /* 剩余字节数为0 */
}
/*
* 从接收FIFO中读数据
*/
while (uiNumBytes) {
uiRd = LPSPI_ReadData(__spiBaseGet(uiChannel));
if (pucRxbuf) {
*pucBytes++ = uiRd;
}
uiNumBytes--;
}
}
/*********************************************************************************************************
** 函数名称: __spiIsr
** 功能描述: 发送中断
** 输 入 : pSpiChannel SPI 通道
** uiVector 中断向量号
** 输 出 : NONE
** 返 回 : 中断返回值
*********************************************************************************************************/
static irqreturn_t __spiIsr (__PSPI_CHANNEL pSpiChannel, ULONG uiVector)
{
UINT32 uiStatus;
LPSPI_Type *pBase = __spiBaseGet(pSpiChannel->SPI_uiChannel);
uiStatus = LPSPI_GetStatusFlags(pBase); /* 获得状态寄存器的值 */
LPSPI_ClearStatusFlags(pBase, uiStatus); /* 清除中断标志 */
if (uiStatus & kLPSPI_ReceiveErrorFlag) {
SPI_DEBUG("spi rx error uiStatus is %x!!\n", uiStatus);
}
if (uiStatus & kLPSPI_RxDataReadyFlag) {
if (pSpiChannel->SPI_uiRemainingBytes) {
__spiDataReceive(pSpiChannel); /* 接收数据 */
if(0 == pSpiChannel->SPI_uiRemainingBytes) { /* 消息数量为0 */
LPSPI_DisableInterrupts(pBase, kLPSPI_AllInterruptEnable);
/* 关闭中断 */
}
}
API_SemaphoreBPost(pSpiChannel->SPI_hSignal); /* 释放信号量 */
}
return (LW_IRQ_HANDLED);
}
/*********************************************************************************************************
** 函数名称: __spiInit
** 功能描述: spi 控制器初始化
** 输 入 : uiChannel SPI 通道号
** 输 出 : NONE
** 返 回 : ERROR_NONE
*********************************************************************************************************/
static INT __spiInit (UINT32 uiChannel)
{
LPSPI_Type *pBase = __spiBaseGet(uiChannel);
lpspi_master_config_t masterConfig;
/*
* 设置 LPSPI 时钟源
*/
CLOCK_SetMux(kCLOCK_LpspiMux, LPSPI_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_LpspiDiv, LPSPI_CLOCK_SOURCE_DIVIDER);
pinmuxSpiEnable(uiChannel); /* 管脚复用 */
/*
* 设置默认的传输控制参数
*/
masterConfig.baudRate = BAUDRATE_DEFAULT; /* 设置波特率 */
masterConfig.bitsPerFrame = 8; /* 8 bit 每帧 */
/*
* 默认时钟极性和相位
*/
masterConfig.cpol = kLPSPI_ClockPolarityActiveHigh;
masterConfig.cpha = kLPSPI_ClockPhaseFirstEdge;
masterConfig.direction = kLPSPI_MsbFirst; /* 高字节先发 */
/*
* 内部延时设置
*/
masterConfig.pcsToSckDelayInNanoSec = NSEC / masterConfig.baudRate;
masterConfig.lastSckToPcsDelayInNanoSec = NSEC / masterConfig.baudRate;
masterConfig.betweenTransferDelayInNanoSec = NSEC / masterConfig.baudRate;
masterConfig.whichPcs = kLPSPI_Pcs0; /* 默认片选 PCS0 */
masterConfig.pcsActiveHighOrLow = kLPSPI_PcsActiveLow; /* 片选为低电平有效 */
masterConfig.pinCfg = kLPSPI_SdiInSdoOut; /* SDI 输入、SDO 输出 */
masterConfig.dataOutConfig = kLpspiDataOutRetained; /* 无效片选后,数据保持最后值 */
LPSPI_MasterInit(pBase, &masterConfig, LPSPI_MASTER_CLOCK_FREQ);
/*
* 清中断和状态
*/
LPSPI_ClearStatusFlags(pBase, kLPSPI_AllStatusFlag);
LPSPI_DisableInterrupts(pBase, kLPSPI_AllInterruptEnable);
return (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __spiHwInit
** 功能描述: spi 通道初始化,硬件初始化
** 输 入 : pSpiChannel SPI 通道
** 输 出 : NONE
** 返 回 : ERROR_CODE
*********************************************************************************************************/
static INT __spiHwInit (__PSPI_CHANNEL pSpiChannel)
{
CHAR cName[20]; /* 中断服务函数名称 */
if (LW_NULL == pSpiChannel) { /* 指针有效性判断 */
return (PX_ERROR);
}
if (!pSpiChannel->SPI_bIsInit) { /* 是否进行了控制器初始化 */
if (ERROR_NONE !=__spiInit(pSpiChannel->SPI_uiChannel)) { /* 初始化控制器 */
return (PX_ERROR);
}
pSpiChannel->SPI_bIsInit = LW_TRUE; /* 进行初始化后,置1 */
}
sprintf(cName, "lpspi%d_isr", pSpiChannel->SPI_uiChannel);
API_InterVectorSetPriority(pSpiChannel->SPI_uiIntVector, LPSPI_INT_PRIORITY);
API_InterVectorConnect(pSpiChannel->SPI_uiIntVector,
(PINT_SVR_ROUTINE)__spiIsr,
(PVOID)pSpiChannel,
cName);
API_InterVectorEnable(pSpiChannel->SPI_uiIntVector);
return (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __trySpiTransfer
** 功能描述: spi 传输函数
** 输 入 : pspiChannel SPI 通道
** pSpiAdapter SPI 适配器
** pSpiMsg SPI 传输消息组
** 输 出 : NONE
** 返 回 : ERROR_CODE
*********************************************************************************************************/
static INT __trySpiTransfer(__PSPI_CHANNEL pspiChannel,
PLW_SPI_ADAPTER pSpiAdapter,
PLW_SPI_MESSAGE pSpiMsg)
{
UCHAR *pucTxBuf = LW_NULL;
UCHAR *pucByte = LW_NULL;
LPSPI_Type *pBase = LW_NULL;
UINT uiTimeOut = SPI_TIMEOUT;
INT iWaterMark;
UINT uiOffset;
if ((LW_NULL == pSpiMsg) ||
((LW_NULL == pSpiMsg->SPIMSG_pucWrBuffer) &&
(LW_NULL == pSpiMsg->SPIMSG_pucRdBuffer))) {
SPI_DEBUG("transfer message is invalid\n");
return (PX_ERROR);
}
pBase = __spiBaseGet(pspiChannel->SPI_uiChannel);
pspiChannel->SPI_uiRemainingBytes = pSpiMsg->SPIMSG_uiLen; /* 消息剩余字节数 */
pucTxBuf = pSpiMsg->SPIMSG_pucWrBuffer;
while (pspiChannel->SPI_uiRemainingBytes) { /* 消息剩余字节数不为0 */
pspiChannel->SPI_uiFifoSize = LPSPI_GetRxFifoSize(pBase); /* TX、RX FIFO 大小相同 */
uiOffset = pSpiMsg->SPIMSG_uiLen - pspiChannel->SPI_uiRemainingBytes;
pucByte = (UCHAR *)pucTxBuf + uiOffset; /* 得到剩余消息的位置 */
iWaterMark = min(pspiChannel->SPI_uiRemainingBytes, pspiChannel->SPI_uiFifoSize);
/*
* 设置 RX FIFO 的阈值,没有用到 TX FIFO 阈值,因此随便设置一个
*/
LPSPI_SetFifoWatermarks(pBase, 1, iWaterMark - 1);
/*
* 清空 FIFO、清空状态、失能中断
*/
LPSPI_FlushFifo(pBase, LW_TRUE, LW_TRUE);
LPSPI_ClearStatusFlags(pBase, kLPSPI_AllStatusFlag);
LPSPI_DisableInterrupts(pBase, kLPSPI_AllInterruptEnable);
/*
* 等待 TX FIFO 为空
*/
while (0 != (LPSPI_GetTxFifoCount(pBase)) && (uiTimeOut--)) {
udelay(1);
if (0 == uiTimeOut) {
SPI_DEBUG("tx fifo empty timeout\n");
return (PX_ERROR);
}
}
/*
* 写入发送数据
*/
while (iWaterMark) {
if (pucByte) {
LPSPI_WriteData(pBase, *pucByte++);
} else {
LPSPI_WriteData(pBase, 0);
}
iWaterMark--;
}
/*
* 使能接收和接收错误中断
*/
LPSPI_EnableInterrupts(pBase, kLPSPI_RxInterruptEnable | kLPSPI_ReceiveErrorInterruptEnable);
uiTimeOut = API_SemaphoreBPend(pspiChannel->SPI_hSignal, TIMEOUT);
/* 挂起,等待中断完成 */
if (ERROR_NONE != uiTimeOut) {
SPI_DEBUG("sem timeout, uiTimeOut is %d\n", uiTimeOut);
return (PX_ERROR);
}
}
return (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __spiTransfer
** 功能描述: spi 传输函数
** 输 入 : uiChannel spi 通道号
** pSpiAdapter spi 适配器
** pSpiMsg spi 传输消息组
** iNum 消息数量
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spiTransfer (UINT32 uiChannel,
PLW_SPI_ADAPTER pSpiAdapter,
PLW_SPI_MESSAGE pSpiMsg,
INT iNum)
{
INT iMsgNum;
__PSPI_CHANNEL pspiChannel = &_G_spiChannels[uiChannel];
for (iMsgNum = 0; iMsgNum < iNum; iMsgNum++, pSpiMsg++) { /* 每个 MSG 循环传输 */
pspiChannel->SPI_pMsg = pSpiMsg;
if (ERROR_NONE != __trySpiTransfer(pspiChannel,
pSpiAdapter,
pSpiMsg)) {
SPI_DEBUG("transfer msg_err num %d\n", iMsgNum);
break;
}
}
return (iMsgNum);
}
/*********************************************************************************************************
** 函数名称: __spiMasterCtl
** 功能描述: spi 传输控制函数
** 输 入 : uiChannel spi 通道号
** pSpiAdapter spi 适配器
** iCmd spi 命令
** lArg spi 参数
** 输 出 : NONE
** 返 回 : ERROR_CODE
*********************************************************************************************************/
static INT __spiMasterCtl (UINT uiChannel,
PLW_SPI_ADAPTER pSpiAdapter,
INT iCmd,
ULONG ulArg)
{
LPSPI_Type *pBase = LW_NULL;
SPI_ARG *pArg = LW_NULL;
UINT uiPcs;
lpspi_master_config_t masterConfig;
if (uiChannel >= SPI_CHANNEL_NUM) {
SPI_DEBUG("channel num error\n");
return (PX_ERROR);
}
pBase = __spiBaseGet(uiChannel);
pArg = (SPI_ARG *)ulArg;
uiPcs = (pArg->SPI_ucFlags & SPI_M_PCS_MASK) >> SPI_M_PCS_SHIFT;
masterConfig.baudRate = pArg->SPI_ulBaud; /* 波特率 */
masterConfig.bitsPerFrame = 8; /* 每帧 8 bit 数据 */
masterConfig.cpol = (pArg->SPI_ucFlags & SPI_M_CPOL_1) ? 1 : 0;
/* CPOL 位 */
masterConfig.cpha = (pArg->SPI_ucFlags & SPI_M_CPHA_1) ? 1 :0 ;
masterConfig.direction = kLPSPI_MsbFirst; /* 高位先发 */
masterConfig.pcsToSckDelayInNanoSec = NSEC / masterConfig.baudRate;
masterConfig.lastSckToPcsDelayInNanoSec = NSEC / masterConfig.baudRate;
masterConfig.betweenTransferDelayInNanoSec = NSEC / masterConfig.baudRate;
masterConfig.whichPcs = uiPcs; /* 片选管脚 */
masterConfig.pcsActiveHighOrLow = kLPSPI_PcsActiveLow; /* 片选电平为低时有效 */
masterConfig.pinCfg = kLPSPI_SdiInSdoOut;
masterConfig.dataOutConfig = kLpspiDataOutRetained;
LPSPI_MasterInit(pBase, &masterConfig, LPSPI_MASTER_CLOCK_FREQ);
return (ERROR_NONE);
}
/*********************************************************************************************************
** 函数名称: __spi0Transfer
** 功能描述: spi0 传输函数
** 输 入 : pSpiAdapter spi 适配器
** pSpiMsg spi 传输消息组
** iNum 消息数量
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi0Transfer (PLW_SPI_ADAPTER pSpiadapter,
PLW_SPI_MESSAGE pSpiMsg,
INT iNum)
{
return (__spiTransfer(SPI_CHANNEL_0,
pSpiadapter,
pSpiMsg,
iNum));
}
/*********************************************************************************************************
** 函数名称: __spi0MasterCtl
** 功能描述: spi0 传输控制函数
** 输 入 : pSpiAdapter spi 适配器
** iCmd 控制命令
** lArg 控制参数
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi0MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
INT iCmd,
LONG lArg)
{
return (__spiMasterCtl(SPI_CHANNEL_0,
pSpiAdapter,
iCmd,
lArg));
}
/*********************************************************************************************************
** 函数名称: __spi1Transfer
** 功能描述: spi1 传输函数
** 输 入 : pSpiAdapter spi 适配器
** pSpiMsg spi 传输消息组
** iNum 消息数量
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi1Transfer (PLW_SPI_ADAPTER pSpiAdapter,
PLW_SPI_MESSAGE pSpiMsg,
INT iNum)
{
return (__spiTransfer(SPI_CHANNEL_1,
pSpiAdapter,
pSpiMsg,
iNum));
}
/*********************************************************************************************************
** 函数名称: __spi1MasterCtl
** 功能描述: spi1 传输控制函数
** 输 入 : pSpiAdapter spi 适配器
** iCmd 控制命令
** lArg 控制参数
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi1MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
INT iCmd,
LONG lArg)
{
return (__spiMasterCtl(SPI_CHANNEL_1,
pSpiAdapter,
iCmd,
lArg));
}
/*********************************************************************************************************
** 函数名称: __spi2Transfer
** 功能描述: spi2 传输函数
** 输 入 : pSpiAdapter spi 适配器
** pSpiMsg spi 传输消息组
** iNum 消息数量
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi2Transfer (PLW_SPI_ADAPTER pSpiAdapter,
PLW_SPI_MESSAGE pSpiMsg,
INT iNum)
{
return (__spiTransfer(SPI_CHANNEL_2,
pSpiAdapter,
pSpiMsg,
iNum));
}
/*********************************************************************************************************
** 函数名称: __spi2MasterCtl
** 功能描述: spi2 传输控制函数
** 输 入 : pSpiAdapter spi 适配器
** iCmd 控制命令
** lArg 控制参数
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi2MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
INT iCmd,
LONG lArg)
{
return (__spiMasterCtl(SPI_CHANNEL_2,
pSpiAdapter,
iCmd,
lArg));
}
/*********************************************************************************************************
** 函数名称: __spi3Transfer
** 功能描述: spi3 传输函数
** 输 入 : pSpiAdapter spi 适配器
** pSpiMsg spi 传输消息组
** iNum 消息数量
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi3Transfer (PLW_SPI_ADAPTER pSpiAdapter,
PLW_SPI_MESSAGE pSpiMsg,
INT iNum)
{
return (__spiTransfer(SPI_CHANNEL_3,
pSpiAdapter,
pSpiMsg,
iNum));
}
/*********************************************************************************************************
** 函数名称: __spi3MasterCtl
** 功能描述: spi3 传输控制函数
** 输 入 : pSpiAdapter spi 适配器
** iCmd 控制命令
** lArg 控制参数
** 输 出 : NONE
** 返 回 : 完成传输的消息数量
*********************************************************************************************************/
static INT __spi3MasterCtl (PLW_SPI_ADAPTER pSpiAdapter,
INT iCmd,
LONG lArg)
{
return (__spiMasterCtl(SPI_CHANNEL_3,
pSpiAdapter,
iCmd,
lArg));
}
/*********************************************************************************************************
SPI总线函数集
*********************************************************************************************************/
static LW_SPI_FUNCS _G_spiFuncs[SPI_CHANNEL_NUM] = {
{
__spi0Transfer,
__spi0MasterCtl,
},
{
__spi1Transfer,
__spi1MasterCtl,
},
{
__spi2Transfer,
__spi2MasterCtl,
},
{
__spi3Transfer,
__spi3MasterCtl,
}
};
/*********************************************************************************************************
** 函数名称: __spiBusDrv
** 功能描述: 初始化 spi 总线并获取操作函数集
** 输 入: uiChannel 通道号
** 输 出: NONE
** 返 回 : spi总线驱动程序
*********************************************************************************************************/
static PLW_SPI_FUNCS __spiBusDrv (UINT32 uiChannel)
{
CHAR cName[20];
if (uiChannel >= SPI_CHANNEL_NUM) { /* 通道号有效性判断 */
SPI_DEBUG("spi channel invalid!\n");
return (LW_NULL);
}
sprintf(cName, "spi%d_sem", uiChannel);
_G_spiChannels[uiChannel].SPI_hSignal = API_SemaphoreBCreate(cName,
LW_FALSE,
LW_OPTION_OBJECT_LOCAL,
LW_NULL);
if (LW_HANDLE_INVALID == _G_spiChannels[uiChannel].SPI_hSignal) {
SPI_DEBUG("fail to create signal\n");
return (LW_NULL);
}
if (ERROR_NONE != __spiHwInit(&_G_spiChannels[uiChannel])) { /* 判断硬件初始化是否成功 */
SPI_DEBUG("fail to init hardware\n");
API_SemaphoreBDelete(&_G_spiChannels[uiChannel].SPI_hSignal);
return (LW_NULL);
}
return (&_G_spiFuncs[uiChannel]); /* 返回操作函数集 */
}
/*********************************************************************************************************
** 函数名称: spiBusCreate
** 功能描述: 初始化目标电路板spi总线系统
** 输 入 : NONE
** 输 出 : NONE
** 返 回 : NONE
*********************************************************************************************************/
VOID spiBusCreate (VOID)
{
PLW_SPI_FUNCS pSpiFuncs = LW_NULL;
API_SpiLibInit(); /* 初始化 spi 组件库 */
pSpiFuncs = __spiBusDrv(SPI_CHANNEL_0);
if (LW_NULL != pSpiFuncs) { /* 判断是否正常获取SPI函数集 */
API_SpiAdapterCreate("/bus/spi/0", pSpiFuncs); /* 创建spi0 总线适配器 */
}
pSpiFuncs = __spiBusDrv(SPI_CHANNEL_2);
if (LW_NULL != pSpiFuncs) { /* 判断是否正常获取SPI函数集 */
API_SpiAdapterCreate("/bus/spi/2", pSpiFuncs); /* 创建spi2 总线适配器 */
}
}
/*********************************************************************************************************
END
*********************************************************************************************************/